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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org