ServletContext#setRequestCharacterEncoding and ServletContext#setResponseCharacterEncoding seem to fail to set the character encoding(WildFly16)
tmk310st May 15, 2019 6:42 PMHello,
Does WildFly-16 support using ServletContext#setRequestCharacterEncoding and ServletContext#setResponseCharacterEncoding?
WildFly-16.0.0.Final supports Java EE 8(https://docs.wildfly.org/) ,
so I am trying to use ServletContext#setRequestCharacterEncoding and ServletContext#setResponseCharacterEncoding
(available in Servlet 4.0).
However, when I created a simple war application and tested them,
they failed to set the character encoding.
[Environment]
- Wildfly-16.0.0.Final (I didn't change any default configuration.)
- jdk11
- Windows 8.1
Here are the application's configuration and components.
[standalone.xml]
(I didn't specify default-encoding for the purpose of testing)
<subsystem xmlns="urn:jboss:domain:undertow:8.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}"> <buffer-cache name="default"/> <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/> <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/> <host name="default-host" alias="localhost"> <location name="/" handler="welcome-content"/> <http-invoker security-realm="ApplicationRealm"/> </host> </server> <servlet-container name="default"> <jsp-config/> <websockets/> </servlet-container> <handlers> <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/> </handlers> </subsystem>
[pom.xml]
(just one dependency)
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
[index.html]
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <form action="/SimpleWarApp/app/simple" method="post"> <!-- The value is Japanese character '\u3042' --> <input type="text" name="hello" value="あ"/> <input type="submit" value="submit!"/> </form> <button type="button" id="the_button">post</button> <script> document.getElementById('the_button').addEventListener('click', function() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.status === 200 && this.readyState === this.DONE) { alert(this.responseText); } }; <!-- Decode the response body by UTF-8 --> xhttp.overrideMimeType('Content-Type: text/plain; charset=UTF-8'); xhttp.open('POST', '/SimpleWarApp/app/simple'); <!-- For the purpose of testing, I intentionally omit charset parameter from Content-Type header, --> <!-- so I can avoid charset parameter to have an effect on the character encoding of servlets. --> <!-- Even when charset parameter is omitted, XMLHttpRequest encodes the request body by UTF-8. --> xhttp.setRequestHeader('Content-Type', 'text/plain'); <!-- The body content is Japanese character '\u3042' --> xhttp.send('あ'); }); </script> </body> </html>
[InitServletContextListener.java]
@WebListener public class InitServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { sce.getServletContext().setRequestCharacterEncoding("UTF-8"); sce.getServletContext().setResponseCharacterEncoding("UTF-8"); } }
[SimpleServlet.java]
@WebServlet("/app/simple") @SuppressWarnings("serial") public class SimpleServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("requestCharacterEncoding : " + req.getServletContext().getRequestCharacterEncoding()); System.out.println("req.getCharacterEncoding() : " + req.getCharacterEncoding()); System.out.println("responseCharacterEncoding : " + req.getServletContext().getResponseCharacterEncoding()); System.out.println("resp.getCharacterEncoding() : " + resp.getCharacterEncoding()); String hello = req.getParameter("hello"); if (hello != null) { System.out.println("hello( expected:E3 81 82 ) : " + toHexString(req.getParameter("hello"))); } else { System.out.println("body( expected:E3 81 82 ) : " + toHexString(req.getReader().readLine())); } resp.getWriter().println("あ"); } // To avoid the platform default encoding to affect assertion, I check the text in hexadecimal format. private String toHexString(String str) throws UnsupportedEncodingException { String ret = ""; for (int b : str.getBytes("UTF-8")) { if (b < 256) { b += 256; } ret += " "; ret += Integer.toHexString(b).toUpperCase(); } return ret; } } }
It doesn't have any servlet filters, web.xml and jboss-web.xml.
The above three(html, listener and servlet) are all the components of this application.
I checked the application's behavior as follows.
Case 1:
When I submit the form with 'hello' parameter, the value of 'hello' parameter is not successfully decoded.
23:59:39,635 INFO [stdout] (default task-1) requestCharacterEncoding : /SimpleWarApp
23:59:39,637 INFO [stdout] (default task-1) req.getCharacterEncoding() : ISO-8859-1
23:59:39,637 INFO [stdout] (default task-1) responseCharacterEncoding : UTF-8
23:59:39,638 INFO [stdout] (default task-1) resp.getCharacterEncoding() : ISO-8859-1
23:59:39,657 INFO [stdout] (default task-1) hello( expected:E3 81 82 ) : C3 A3 C2 81 C2 82
Case 2:
When I click 'post' button and send text contents, the request body (one Japanese character) is not successfully decoded,
23:55:30,854 INFO [stdout] (default task-1) requestCharacterEncoding : /SimpleWarApp
23:55:30,855 INFO [stdout] (default task-1) req.getCharacterEncoding() : ISO-8859-1
23:55:30,857 INFO [stdout] (default task-1) responseCharacterEncoding : UTF-8
23:55:30,858 INFO [stdout] (default task-1) resp.getCharacterEncoding() : ISO-8859-1
23:55:30,863 INFO [stdout] (default task-1) body( expected:E3 81 82 ) : C3 A3 C2 81 C2 82
In both Case 1 and Case 2, I expected the response body to be encoded by UTF-8 (expected: E3 81 82 0A) but it was not encoded successfully
(I checked the response body in hexadecimal form by using Fiddler).
3F 0A
However, when I remove InitServletContextListener.java from the application and set the character encoding
by using HttpServetRequest#setCharacterEncoding and HttpServletResponse#setCharacterEncoding at the beginning of 'doPost' method,
It seems to work fine as follows.
(In Case 1)
00:05:33,194 INFO [stdout] (default task-1) req.getCharacterEncoding() : UTF-8
00:05:33,197 INFO [stdout] (default task-1) resp.getCharacterEncoding() : UTF-8
00:05:33,199 INFO [stdout] (default task-1) hello( expected:E3 81 82 ) : E3 81 82
(In Case 2)
00:05:27,814 INFO [stdout] (default task-1) req.getCharacterEncoding() : UTF-8
00:05:27,816 INFO [stdout] (default task-1) resp.getCharacterEncoding() : UTF-8
00:05:27,843 INFO [stdout] (default task-1) body( expected:E3 81 82 ) : E3 81 82
(The response body)
E3 81 82 0A
Thanks,
Tomoki