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





