5 Replies Latest reply on May 16, 2019 10:08 AM by Tomoki Sato

    ServletContext#setRequestCharacterEncoding and ServletContext#setResponseCharacterEncoding seem to fail to set the character encoding(WildFly16)

    Tomoki Sato Newbie

      Hello,

       

      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