You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2023/01/18 15:35:57 UTC

[tomcat] branch main updated: Implement new methods for setting character encoding

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new b1008bf815 Implement new methods for setting character encoding
b1008bf815 is described below

commit b1008bf81591d856368fdf5aa9a693e01bfdad3d
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Jan 17 16:55:57 2023 +0000

    Implement new methods for setting character encoding
---
 java/jakarta/servlet/ServletContext.java           | 45 +++++++++++++++++
 java/jakarta/servlet/ServletRequest.java           | 34 ++++++++++---
 java/jakarta/servlet/ServletRequestWrapper.java    | 10 ++++
 java/jakarta/servlet/ServletResponse.java          | 58 +++++++++++++++++++---
 java/jakarta/servlet/ServletResponseWrapper.java   | 12 +++++
 .../apache/catalina/connector/TestResponse.java    |  4 +-
 webapps/docs/changelog.xml                         |  4 ++
 7 files changed, 151 insertions(+), 16 deletions(-)

diff --git a/java/jakarta/servlet/ServletContext.java b/java/jakarta/servlet/ServletContext.java
index 97a99d6872..96d4a1dc52 100644
--- a/java/jakarta/servlet/ServletContext.java
+++ b/java/jakarta/servlet/ServletContext.java
@@ -19,6 +19,7 @@ package jakarta.servlet;
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.charset.Charset;
 import java.util.Enumeration;
 import java.util.EventListener;
 import java.util.Map;
@@ -969,6 +970,28 @@ public interface ServletContext {
      */
     public void setRequestCharacterEncoding(String encoding);
 
+    /**
+     * Sets the request character encoding for this ServletContext.
+     *
+     * <p>Implementations are strongly encouraged to override this default
+     * method and provide a more efficient implementation.
+     *
+     * @param encoding request character encoding
+     *
+     * @throws IllegalStateException if this ServletContext has already been
+     *     initialized
+     * @throws UnsupportedOperationException if this ServletContext was passed
+     *     to the {@link ServletContextListener#contextInitialized} method of a
+     *     {@link ServletContextListener} that was neither declared in
+     *     {@code web.xml} or {@code web-fragment.xml}, nor annotated with
+     *     {@link jakarta.servlet.annotation.WebListener}
+     *
+     * @since Servlet 6.1
+     */
+    public default void setRequestCharacterEncoding(Charset encoding) {
+        setRequestCharacterEncoding(encoding.name());
+    }
+
     /**
      * Get the default character encoding for writing response bodies.
      *
@@ -979,6 +1002,28 @@ public interface ServletContext {
      */
     public String getResponseCharacterEncoding();
 
+    /**
+     * Sets the response character encoding for this ServletContext.
+     *
+     * <p>Implementations are strongly encouraged to override this default
+     * method and provide a more efficient implementation.
+     *
+     * @param encoding response character encoding
+     *
+     * @throws IllegalStateException if this ServletContext has already been
+     *     initialized
+     * @throws UnsupportedOperationException if this ServletContext was passed
+     *     to the {@link ServletContextListener#contextInitialized} method of a
+     *     {@link ServletContextListener} that was neither declared in
+     *     {@code web.xml} or {@code web-fragment.xml}, nor annotated with
+     *     {@link jakarta.servlet.annotation.WebListener}
+     *
+     * @since Servlet 6.1
+     */
+    public default void setResponseCharacterEncoding(Charset encoding) {
+        setResponseCharacterEncoding(encoding.name());
+    }
+
     /**
      * Set the default character encoding to use for writing response bodies.
      * Calling this method will over-ride any value set in the deployment
diff --git a/java/jakarta/servlet/ServletRequest.java b/java/jakarta/servlet/ServletRequest.java
index ea0c549e4b..ed0272a528 100644
--- a/java/jakarta/servlet/ServletRequest.java
+++ b/java/jakarta/servlet/ServletRequest.java
@@ -18,6 +18,8 @@ package jakarta.servlet;
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
 import java.util.Enumeration;
 import java.util.Locale;
 import java.util.Map;
@@ -97,14 +99,34 @@ public interface ServletRequest {
      * request. This method must be called prior to reading request parameters
      * or reading input using getReader().
      *
-     * @param env
-     *            a <code>String</code> containing the name of the character
-     *            encoding.
-     * @throws java.io.UnsupportedEncodingException
+     * @param encoding a {@code String} containing the name of the character
+     *     encoding
+     *
+     * @throws UnsupportedEncodingException
      *             if this is not a valid encoding
      */
-    public void setCharacterEncoding(String env)
-            throws java.io.UnsupportedEncodingException;
+    public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException;
+
+
+    /**
+     * Overrides the character encoding used in the body of this request. This
+     * method must be called prior to reading request parameters or reading
+     * input using getReader(). Otherwise, it has no effect.
+     *
+     * <p>Implementations are strongly encouraged to override this default
+     * method and provide a more efficient implementation.
+     *
+     * @param encoding {@code Charset} representing the character encoding.
+     *
+     * @since Servlet 6.1
+     */
+    public default void setCharacterEncoding(Charset encoding) {
+        try {
+            setCharacterEncoding(encoding.name());
+        } catch (UnsupportedEncodingException e) {
+            // Unreachable code
+        }
+    }
 
     /**
      * Returns the length, in bytes, of the request body and made available by
diff --git a/java/jakarta/servlet/ServletRequestWrapper.java b/java/jakarta/servlet/ServletRequestWrapper.java
index 094d4686ca..0ffabc806a 100644
--- a/java/jakarta/servlet/ServletRequestWrapper.java
+++ b/java/jakarta/servlet/ServletRequestWrapper.java
@@ -18,6 +18,7 @@ package jakarta.servlet;
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.nio.charset.Charset;
 import java.util.Enumeration;
 import java.util.Locale;
 import java.util.Map;
@@ -113,6 +114,15 @@ public class ServletRequestWrapper implements ServletRequest {
         this.request.setCharacterEncoding(enc);
     }
 
+    /**
+     * The default behavior of this method is to set the character encoding on
+     * the wrapped request object.
+     */
+    @Override
+    public void setCharacterEncoding(Charset encoding) {
+        this.request.setCharacterEncoding(encoding);
+    }
+
     /**
      * The default behavior of this method is to return getContentLength() on
      * the wrapped request object.
diff --git a/java/jakarta/servlet/ServletResponse.java b/java/jakarta/servlet/ServletResponse.java
index 595051515a..c71a7fffc7 100644
--- a/java/jakarta/servlet/ServletResponse.java
+++ b/java/jakarta/servlet/ServletResponse.java
@@ -18,6 +18,7 @@ package jakarta.servlet;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.nio.charset.Charset;
 import java.util.Locale;
 
 /**
@@ -150,8 +151,9 @@ public interface ServletResponse {
      * Sets the character encoding (MIME charset) of the response being sent to
      * the client, for example, to UTF-8. If the character encoding has already
      * been set by container default, ServletContext default,
-     * {@link #setContentType} or {@link #setLocale}, this method overrides it.
-     * Calling {@link #setContentType} with the <code>String</code> of
+     * {@link #setCharacterEncoding(Charset)}, {@link #setContentType} or
+     * {@link #setLocale}, this method overrides it. Calling
+     * {@link #setContentType} with the <code>String</code> of
      * <code>text/html</code> and calling this method with the
      * <code>String</code> of <code>UTF-8</code> is equivalent with calling
      * <code>setContentType</code> with the <code>String</code> of
@@ -173,11 +175,49 @@ public interface ServletResponse {
      *            a String specifying only the character set defined by IANA
      *            Character Sets
      *            (http://www.iana.org/assignments/character-sets)
+     *
      * @see #setContentType #setLocale
+     * @see #setCharacterEncoding(Charset)
+     *
      * @since Servlet 2.4
      */
     public void setCharacterEncoding(String charset);
 
+    /**
+     * Sets the character encoding (MIME charset) of the response being sent to
+     * the client, for example, to UTF-8. If the character encoding has already
+     * been set by container default, ServletContext default,
+     * {@link #setCharacterEncoding(String)}, {@link #setContentType} or
+     * {@link #setLocale}, this method overrides it. Calling
+     * {@link #setContentType} with the <code>String</code> of
+     * <code>text/html</code> and calling this method with the
+     * <code>StandardCharsets.UTF-8</code> is equivalent with calling
+     * <code>setContentType</code> with the <code>String</code> of
+     * <code>text/html; charset=UTF-8</code>.
+     * <p>
+     * This method can be called repeatedly to change the character encoding.
+     * This method has no effect if it is called after <code>getWriter</code>
+     * has been called or after the response has been committed.
+     * <p>
+     * Containers must communicate the character encoding used for the servlet
+     * response's writer to the client if the protocol provides a way for doing
+     * so. In the case of HTTP, the character encoding is communicated as part
+     * of the <code>Content-Type</code> header for text media types. Note that
+     * the character encoding cannot be communicated via HTTP headers if the
+     * servlet does not specify a content type; however, it is still used to
+     * encode text written via the servlet response's writer.
+     *
+     * @param encoding The encoding to use or {@code null}
+     *
+     * @see #setContentType #setLocale
+     * @see #setCharacterEncoding(String)
+     *
+     * @since Servlet 6.1
+     */
+    public default void setCharacterEncoding(Charset encoding) {
+       setCharacterEncoding(encoding.name());
+    }
+
     /**
      * Sets the length of the content body in the response In HTTP servlets,
      * this method sets the HTTP Content-Length header.
@@ -323,9 +363,10 @@ public interface ServletResponse {
      * Sets the locale of the response, if the response has not been committed
      * yet. It also sets the response's character encoding appropriately for the
      * locale, if the character encoding has not been explicitly set using
-     * {@link #setContentType} or {@link #setCharacterEncoding},
-     * <code>getWriter</code> hasn't been called yet, and the response hasn't
-     * been committed yet. If the deployment descriptor contains a
+     * {@link #setContentType}, {@link #setCharacterEncoding(String)} or
+     * {@link #setCharacterEncoding(Charset)}, <code>getWriter</code> hasn't
+     * been called yet, and the response hasn't been committed yet. If the
+     * deployment descriptor contains a
      * <code>locale-encoding-mapping-list</code> element, and that element
      * provides a mapping for the given locale, that mapping is used. Otherwise,
      * the mapping from locale to character encoding is container dependent.
@@ -347,11 +388,12 @@ public interface ServletResponse {
      * servlet does not specify a content type; however, it is still used to
      * encode text written via the servlet response's writer.
      *
-     * @param loc
-     *            the locale of the response
+     * @param loc the locale of the response
+     *
      * @see #getLocale
      * @see #setContentType
-     * @see #setCharacterEncoding
+     * @see #setCharacterEncoding(String)
+     * @see #setCharacterEncoding(Charset)
      */
     public void setLocale(Locale loc);
 
diff --git a/java/jakarta/servlet/ServletResponseWrapper.java b/java/jakarta/servlet/ServletResponseWrapper.java
index eb5119497c..96fd8a4206 100644
--- a/java/jakarta/servlet/ServletResponseWrapper.java
+++ b/java/jakarta/servlet/ServletResponseWrapper.java
@@ -18,6 +18,7 @@ package jakarta.servlet;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.nio.charset.Charset;
 import java.util.Locale;
 import java.util.ResourceBundle;
 
@@ -87,6 +88,17 @@ public class ServletResponseWrapper implements ServletResponse {
         this.response.setCharacterEncoding(charset);
     }
 
+    /**
+     * The default behavior of this method is to call
+     * {@code setCharacterEncoding(Charset)} on the wrapped response object.
+     *
+     * @since Servlet 6.1
+     */
+    @Override
+    public void setCharacterEncoding(Charset encoding) {
+        this.response.setCharacterEncoding(encoding);
+    }
+
     /**
      * The default behavior of this method is to return getCharacterEncoding()
      * on the wrapped response object.
diff --git a/test/org/apache/catalina/connector/TestResponse.java b/test/org/apache/catalina/connector/TestResponse.java
index 73ee4674f1..56ab01bb26 100644
--- a/test/org/apache/catalina/connector/TestResponse.java
+++ b/test/org/apache/catalina/connector/TestResponse.java
@@ -705,7 +705,7 @@ public class TestResponse extends TomcatBaseTest {
         Assert.assertEquals(ISO_8859_1, response.getCharacterEncoding());
         response.setCharacterEncoding(UTF_8);
         Assert.assertEquals(UTF_8, response.getCharacterEncoding());
-        response.setCharacterEncoding(null);
+        response.setCharacterEncoding((String) null);
         Assert.assertEquals(ISO_8859_1, response.getCharacterEncoding());
     }
 
@@ -923,7 +923,7 @@ public class TestResponse extends TomcatBaseTest {
         Assert.assertEquals(UTF_8, response.getCharacterEncoding());
 
         // Reset
-        response.setCharacterEncoding(null);
+        response.setCharacterEncoding((String) null);
         Assert.assertEquals(ISO_8859_1, response.getCharacterEncoding());
 
         // setLocale is over-ridden by setCharacterEncoding
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 967144142a..31d232d01f 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -111,6 +111,10 @@
         Allow a Valve to access cookies from a request that cannot be mapped to
         a Context. (markt)
       </fix>
+      <add>
+        Implement the new Servlet API methods for setting character encodings
+        that accept {@code Charset} objects. (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Other">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: [tomcat] branch main updated: Implement new methods for setting character encoding

Posted by Mark Thomas <ma...@apache.org>.
On 18/01/2023 15:35, markt@apache.org wrote:
> This is an automated email from the ASF dual-hosted git repository.
> 
> markt pushed a commit to branch main
> in repository https://gitbox.apache.org/repos/asf/tomcat.git
> 
> 
> The following commit(s) were added to refs/heads/main by this push:
>       new b1008bf815 Implement new methods for setting character encoding
> b1008bf815 is described below
> 
> commit b1008bf81591d856368fdf5aa9a693e01bfdad3d
> Author: Mark Thomas <ma...@apache.org>
> AuthorDate: Tue Jan 17 16:55:57 2023 +0000
> 
>      Implement new methods for setting character encoding

FYI I am currently exploring options to use some form of CharsetHolder 
internally rather than storing the Charset and the name separately in 
the request and response. I think that will simplify the code a little.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org