Skip to content

Commit ba27532

Browse files
committed
Fix jakartaee#415 - add overloaded setCharacterEncoding() supporting Charset
1 parent 89d21f7 commit ba27532

File tree

6 files changed

+168
-38
lines changed

6 files changed

+168
-38
lines changed

api/src/main/java/jakarta/servlet/ServletContext.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.InputStream;
2323
import java.net.MalformedURLException;
2424
import java.net.URL;
25+
import java.nio.charset.Charset;
2526
import java.util.Enumeration;
2627
import java.util.EventListener;
2728
import java.util.Map;
@@ -1342,6 +1343,26 @@ public interface ServletContext {
13421343
*/
13431344
public void setRequestCharacterEncoding(String encoding);
13441345

1346+
/**
1347+
* Sets the request character encoding for this ServletContext.
1348+
* <p>
1349+
* Implementations are strongly encouraged to override this default method and provide a more efficient implementation.
1350+
*
1351+
* @param encoding request character encoding
1352+
*
1353+
* @throws IllegalStateException if this ServletContext has already been initialized
1354+
*
1355+
* @throws UnsupportedOperationException if this ServletContext was passed to the
1356+
* {@link ServletContextListener#contextInitialized} method of a {@link ServletContextListener} that was neither
1357+
* declared in <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated with
1358+
* {@link jakarta.servlet.annotation.WebListener}
1359+
*
1360+
* @since Servlet 6.1
1361+
*/
1362+
default public void setRequestCharacterEncoding(Charset encoding) {
1363+
setRequestCharacterEncoding(encoding.name());
1364+
}
1365+
13451366
/**
13461367
* Gets the response character encoding that are supported by default for this <tt>ServletContext</tt>. This method
13471368
* returns null if no response encoding character encoding has been specified in deployment descriptor or container
@@ -1368,4 +1389,24 @@ public interface ServletContext {
13681389
* @since Servlet 4.0
13691390
*/
13701391
public void setResponseCharacterEncoding(String encoding);
1392+
1393+
/**
1394+
* Sets the response character encoding for this ServletContext.
1395+
* <p>
1396+
* Implementations are strongly encouraged to override this default method and provide a more efficient implementation.
1397+
*
1398+
* @param encoding response character encoding
1399+
*
1400+
* @throws IllegalStateException if this ServletContext has already been initialized
1401+
*
1402+
* @throws UnsupportedOperationException if this ServletContext was passed to the
1403+
* {@link ServletContextListener#contextInitialized} method of a {@link ServletContextListener} that was neither
1404+
* declared in <code>web.xml</code> or <code>web-fragment.xml</code>, nor annotated with
1405+
* {@link jakarta.servlet.annotation.WebListener}
1406+
*
1407+
* @since Servlet 6.1
1408+
*/
1409+
default public void setResponseCharacterEncoding(Charset encoding) {
1410+
setResponseCharacterEncoding(encoding.name());
1411+
}
13711412
}

api/src/main/java/jakarta/servlet/ServletRequest.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2021 Oracle and/or its affiliates and others.
2+
* Copyright (c) 1997, 2022 Oracle and/or its affiliates and others.
33
* All rights reserved.
44
* Copyright 2004 The Apache Software Foundation
55
*
@@ -19,6 +19,7 @@
1919
package jakarta.servlet;
2020

2121
import java.io.*;
22+
import java.nio.charset.Charset;
2223
import java.util.*;
2324

2425
/**
@@ -83,12 +84,30 @@ public interface ServletRequest {
8384
* Overrides the name of the character encoding used in the body of this request. This method must be called prior to
8485
* reading request parameters or reading input using getReader(). Otherwise, it has no effect.
8586
*
86-
* @param env <code>String</code> containing the name of the character encoding.
87+
* @param encoding <code>String</code> containing the name of the character encoding.
8788
*
8889
* @throws UnsupportedEncodingException if this ServletRequest is still in a state where a character encoding may be
8990
* set, but the specified encoding is invalid
9091
*/
91-
public void setCharacterEncoding(String env) throws UnsupportedEncodingException;
92+
public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException;
93+
94+
/**
95+
* Overrides the character encoding used in the body of this request. This method must be called prior to reading
96+
* request parameters or reading input using getReader(). Otherwise, it has no effect.
97+
* <p>
98+
* Implementations are strongly encouraged to override this default method and provide a more efficient implementation.
99+
*
100+
* @param encoding <code>Charset</code> representing the character encoding.
101+
*
102+
* @since Servlet 6.1
103+
*/
104+
default public void setCharacterEncoding(Charset encoding) {
105+
try {
106+
setCharacterEncoding(encoding.name());
107+
} catch (UnsupportedEncodingException e) {
108+
// Unreachable code
109+
}
110+
}
92111

93112
/**
94113
* Returns the length, in bytes, of the request body and made available by the input stream, or -1 if the length is not

api/src/main/java/jakarta/servlet/ServletRequestWrapper.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2021 Oracle and/or its affiliates and others.
2+
* Copyright (c) 1997, 2022 Oracle and/or its affiliates and others.
33
* All rights reserved.
44
* Copyright 2004 The Apache Software Foundation
55
*
@@ -21,6 +21,7 @@
2121
import java.io.BufferedReader;
2222
import java.io.IOException;
2323
import java.io.UnsupportedEncodingException;
24+
import java.nio.charset.Charset;
2425
import java.util.Enumeration;
2526
import java.util.Locale;
2627
import java.util.Map;
@@ -104,8 +105,16 @@ public String getCharacterEncoding() {
104105
* The default behavior of this method is to set the character encoding on the wrapped request object.
105106
*/
106107
@Override
107-
public void setCharacterEncoding(String enc) throws UnsupportedEncodingException {
108-
this.request.setCharacterEncoding(enc);
108+
public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException {
109+
this.request.setCharacterEncoding(encoding);
110+
}
111+
112+
/**
113+
* The default behavior of this method is to set the character encoding on the wrapped request object.
114+
*/
115+
@Override
116+
public void setCharacterEncoding(Charset encoding) {
117+
this.request.setCharacterEncoding(encoding);
109118
}
110119

111120
/**

api/src/main/java/jakarta/servlet/ServletResponse.java

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.io.IOException;
2222
import java.io.PrintWriter;
2323
import java.io.UnsupportedEncodingException;
24+
import java.nio.charset.Charset;
25+
import java.nio.charset.StandardCharsets;
2426
import java.util.Locale;
2527

2628
/**
@@ -38,11 +40,12 @@
3840
* request, per web-app (using {@link ServletContext#setRequestCharacterEncoding}, deployment descriptor), and per
3941
* container (for all web applications deployed in that container, using vendor specific configuration). If multiple of
4042
* the preceding techniques have been employed, the priority is the order listed. For per request, the charset for the
41-
* response can be specified explicitly using the {@link #setCharacterEncoding} and {@link #setContentType} methods, or
42-
* implicitly using the {@link #setLocale} method. Explicit specifications take precedence over implicit specifications.
43-
* If no charset is explicitly specified, ISO-8859-1 will be used. The <code>setCharacterEncoding</code>,
44-
* <code>setContentType</code>, or <code>setLocale</code> method must be called before <code>getWriter</code> and before
45-
* committing the response for the character encoding to be used.
43+
* response can be specified explicitly using the {@link #setCharacterEncoding(String)},
44+
* {@link #setCharacterEncoding(Charset)} and {@link #setContentType} methods, or implicitly using the
45+
* {@link #setLocale} method. Explicit specifications take precedence over implicit specifications. If no charset is
46+
* explicitly specified, ISO-8859-1 will be used. The <code>setCharacterEncoding</code>, <code>setContentType</code>, or
47+
* <code>setLocale</code> method must be called before <code>getWriter</code> and before committing the response for the
48+
* character encoding to be used.
4649
*
4750
* <p>
4851
* See the Internet RFCs such as <a href="http://www.ietf.org/rfc/rfc2045.txt"> RFC 2045</a> for more information on
@@ -60,10 +63,11 @@ public interface ServletResponse {
6063
* perweb-app (using {@link ServletContext#setResponseCharacterEncoding}, deployment descriptor), and per container (for
6164
* all web applications deployed in that container, using vendor specific configuration). The first one of these methods
6265
* that yields a result is returned. Per-request, the charset for the response can be specified explicitly using the
63-
* {@link #setCharacterEncoding} and {@link #setContentType} methods, or implicitly using the
64-
* setLocale(java.util.Locale) method. Explicit specifications take precedence over implicit specifications. Calls made
65-
* to these methods after <code>getWriter</code> has been called or after the response has been committed have no effect
66-
* on the character encoding. If no character encoding has been specified, <code>ISO-8859-1</code> is returned.
66+
* {@link #setCharacterEncoding(String)}, {@link #setCharacterEncoding(Charset)} and {@link #setContentType} methods, or
67+
* implicitly using the setLocale(java.util.Locale) method. Explicit specifications take precedence over implicit
68+
* specifications. Calls made to these methods after <code>getWriter</code> has been called or after the response has
69+
* been committed have no effect on the character encoding. If no character encoding has been specified,
70+
* <code>ISO-8859-1</code> is returned.
6771
* <p>
6872
* See RFC 2047 (http://www.ietf.org/rfc/rfc2047.txt) for more information about character encoding and MIME.
6973
*
@@ -136,18 +140,19 @@ public interface ServletResponse {
136140
/**
137141
* Sets the character encoding (MIME charset) of the response being sent to the client, for example, to UTF-8. If the
138142
* response character encoding has already been set by {@link ServletContext#setResponseCharacterEncoding}, the
139-
* deployment descriptor, or using the {@link #setContentType} or {@link #setLocale} methods, the value set in this
140-
* method overrides all of those values. Calling {@link #setContentType} with the <code>String</code> of
141-
* <code>text/html</code> and calling this method with the <code>String</code> of <code>UTF-8</code> is equivalent to
142-
* calling {@link #setContentType} with the <code>String</code> of <code>text/html; charset=UTF-8</code>.
143+
* deployment descriptor, or using the {@link #setCharacterEncoding(Charset)}, {@link #setContentType} or
144+
* {@link #setLocale} methods, the value set in this method overrides all of those values. Calling
145+
* {@link #setContentType} with the <code>String</code> of <code>text/html</code> and calling this method with the
146+
* <code>String</code> of <code>UTF-8</code> is equivalent to calling {@link #setContentType} with the
147+
* <code>String</code> of <code>text/html; charset=UTF-8</code>.
143148
* <p>
144149
* This method can be called repeatedly to change the character encoding. This method has no effect if it is called
145150
* after <code>getWriter</code> has been called or after the response has been committed.
146151
* <p>
147152
* If calling this method has an effect (as per the previous paragraph), calling this method with {@code null} clears
148-
* any character encoding set via a previous call to this method, {@link #setContentType} or {@link #setLocale} but does
149-
* not affect any default character encoding configured via {@link ServletContext#setResponseCharacterEncoding} or the
150-
* deployment descriptor.
153+
* any character encoding set via a previous call to this method, {@link #setCharacterEncoding(Charset)},
154+
* {@link #setContentType} or {@link #setLocale} but does not affect any default character encoding configured via
155+
* {@link ServletContext#setResponseCharacterEncoding} or the deployment descriptor.
151156
* <p>
152157
* If this method is called with an invalid or unrecognised character encoding, then a subsequent call to
153158
* {@link #getWriter()} will throw a {@link UnsupportedEncodingException}. Content for an unknown encoding can be sent
@@ -161,15 +166,53 @@ public interface ServletResponse {
161166
* HTTP headers if the servlet does not specify a content type; however, it is still used to encode text written via the
162167
* servlet response's writer.
163168
*
164-
* @param charset a String specifying only the character set defined by IANA Character Sets
169+
* @param encoding a String specifying only the character set defined by IANA Character Sets
165170
* (http://www.iana.org/assignments/character-sets) or {@code null}
166171
*
172+
* @see #setCharacterEncoding(Charset)
167173
* @see #setContentType
168174
* @see #setLocale
169175
*
170176
* @since Servlet 2.4
171177
*/
172-
public void setCharacterEncoding(String charset);
178+
public void setCharacterEncoding(String encoding);
179+
180+
/**
181+
* Sets the character encoding (MIME charset) of the response being sent to the client, for example, to UTF-8. If the
182+
* response character encoding has already been set by {@link ServletContext#setResponseCharacterEncoding}, the
183+
* deployment descriptor, or using the {@link #setCharacterEncoding(String)}, {@link #setContentType} or
184+
* {@link #setLocale} methods, the value set in this method overrides all of those values. Calling
185+
* {@link #setContentType} with the <code>String</code> of <code>text/html</code> and calling this method with
186+
* {@link StandardCharsets#UTF_8} is equivalent to calling {@link #setContentType} with the <code>String</code> of
187+
* <code>text/html; charset=UTF-8</code>.
188+
* <p>
189+
* This method can be called repeatedly to change the character encoding. This method has no effect if it is called
190+
* after <code>getWriter</code> has been called or after the response has been committed.
191+
* <p>
192+
* If calling this method has an effect (as per the previous paragraph), calling this method with {@code null} clears
193+
* any character encoding set via a previous call to this method, {@link #setCharacterEncoding(String)},
194+
* {@link #setContentType} or {@link #setLocale} but does not affect any default character encoding configured via
195+
* {@link ServletContext#setResponseCharacterEncoding} or the deployment descriptor.
196+
* <p>
197+
* Containers must communicate the character encoding used for the servlet response's writer to the client if the
198+
* protocol provides a way for doing so. In the case of HTTP, the character encoding is communicated as part of the
199+
* <code>Content-Type</code> header for text media types. Note that the character encoding cannot be communicated via
200+
* HTTP headers if the servlet does not specify a content type; however, it is still used to encode text written via the
201+
* servlet response's writer.
202+
* <p>
203+
* Implementations are strongly encouraged to override this default method and provide a more efficient implementation.
204+
*
205+
* @param encoding a Charset instance representing the encoding to use or {@code null}
206+
*
207+
* @see #setCharacterEncoding(String)
208+
* @see #setContentType
209+
* @see #setLocale
210+
*
211+
* @since Servlet 6.1
212+
*/
213+
default public void setCharacterEncoding(Charset encoding) {
214+
setCharacterEncoding(encoding.name());
215+
}
173216

174217
/**
175218
* Sets the length of the content body in the response In HTTP servlets, this method sets the HTTP Content-Length
@@ -208,8 +251,9 @@ public interface ServletResponse {
208251
* <p>
209252
* If calling this method has an effect (as per the previous paragraph), calling this method with {@code null} clears
210253
* any content type set via a previous call to this method and clears any character encoding set via a previous call to
211-
* this method, {@link #setCharacterEncoding} or {@link #setLocale} but does not affect any default character encoding
212-
* configured via {@link ServletContext#setResponseCharacterEncoding} or the deployment descriptor.
254+
* this method, {@link #setCharacterEncoding(String)}, {@link #setCharacterEncoding(Charset)} or {@link #setLocale} but
255+
* does not affect any default character encoding configured via {@link ServletContext#setResponseCharacterEncoding} or
256+
* the deployment descriptor.
213257
* <p>
214258
* If this method is called with an invalid or unrecognised character encoding, then a subsequent call to
215259
* {@link #getWriter()} will throw a {@link UnsupportedEncodingException}. Content for an unknown encoding can be sent
@@ -224,7 +268,8 @@ public interface ServletResponse {
224268
* @param type a <code>String</code> specifying the MIME type of the content or {@code null}
225269
*
226270
* @see #setLocale
227-
* @see #setCharacterEncoding
271+
* @see #setCharacterEncoding(String)
272+
* @see #setCharacterEncoding(Charset)
228273
* @see #getOutputStream
229274
* @see #getWriter
230275
*
@@ -328,15 +373,16 @@ public interface ServletResponse {
328373
/**
329374
* Sets the locale of the response, if the response has not been committed yet. It also sets the response's character
330375
* encoding appropriately for the locale, if the character encoding has not been explicitly set using
331-
* {@link #setContentType} or {@link #setCharacterEncoding}, <code>getWriter</code> hasn't been called yet, and the
332-
* response hasn't been committed yet. If the deployment descriptor contains a <code>locale-encoding-mapping-list</code>
333-
* element, and that element provides a mapping for the given locale, that mapping is used. Otherwise, the mapping from
334-
* locale to character encoding is container dependent.
376+
* {@link #setContentType}, {@link #setCharacterEncoding(String)} or {@link #setCharacterEncoding(Charset)},
377+
* <code>getWriter</code> hasn't been called yet, and the response hasn't been committed yet. If the deployment
378+
* descriptor contains a <code>locale-encoding-mapping-list</code> element, and that element provides a mapping for the
379+
* given locale, that mapping is used. Otherwise, the mapping from locale to character encoding is container dependent.
335380
* <p>
336381
* This method may be called repeatedly to change locale and character encoding. The method has no effect if called
337382
* after the response has been committed. It does not set the response's character encoding if it is called after
338-
* {@link #setContentType} has been called with a charset specification, after {@link #setCharacterEncoding} has been
339-
* called, after <code>getWriter</code> has been called, or after the response has been committed.
383+
* {@link #setContentType} has been called with a charset specification, after {@link #setCharacterEncoding(String} has
384+
* been called, after {@link #setCharacterEncoding(Charset} has been called, after <code>getWriter</code> has been
385+
* called, or after the response has been committed.
340386
* <p>
341387
* If calling this method has an effect on the locale (as per the previous paragraph), calling this method with
342388
* {@code null} clears any locale set via a previous call to this method. If calling this method has an effect on the
@@ -352,7 +398,8 @@ public interface ServletResponse {
352398
*
353399
* @see #getLocale
354400
* @see #setContentType
355-
* @see #setCharacterEncoding
401+
* @see #setCharacterEncoding(String)
402+
* @see #setCharacterEncoding(Charset)
356403
*/
357404
public void setLocale(Locale loc);
358405

0 commit comments

Comments
 (0)