ServletRequest.setCharacterCoding() Ignored

By , 2 April 2012

ServletRequest.setCharacterCoding() Ignored

Take a look at this block of servlet code and see if you can tell me what the output should be when I send x=éééé

Log.warning(Charset.defaultCharset().toString());
Log.warning(request.getCharacterEncoding());
Log.warning(request.getParameter("x"));
request.setCharacterEncoding("UTF-8");
Log.warning(request.getCharacterEncoding());
Log.warning(request.getParameter("x"));

Well, here is the output

UTF-8
null
éééé
UTF-8
éééé

Compare this code

Log.warning(Charset.defaultCharset());
Log.warning(request.getCharacterEncoding());
request.setCharacterEncoding("UTF-8");
Log.warning(request.getCharacterEncoding());
Log.warning(request.getParameter("x"));

Which gives us something more sensible:

UTF-8
null
UTF-8
éééé

Lesson of the day?

You can't change the request encoding after request.getParameter() has been called.

In my case a third-party filter was causing the damage, so I made a new filter at the top of the chain just to call request.setCharacterEncoding(). Note also that the default character encoding which I set with -Dfile.encoding=UTF-8 had no effect on the decoding of request parameters. Also, the form is POSTed with multipart/form-data and I added accept-charset to force the browser to send UTF-8:

<form method="post" enctype="multipart/form-data" accept-charset="UTF-8" >
  <input type="text" name="x"/>
  <input type="submit"/>
</form>
ServletRequest.setCharacterCoding() Ignored

Here is the filter code for the lazy folks.

/**
 * This filter ensures that all requests and responses are encoded and 
 * decoded with UTF-8. It must appear first in the filter chain, because
 * as soon as you call request.getParameter(), the request encoding cannot
 * be changed.
 */
public class UTF8Filter implements Filter {

    @Override
    public void init(FilterConfig fc) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {}
}

Okay, and the web.xml config for the really lazy folks.

    <!-- Set UTF-8 before request.getParameter() is called -->
    <filter>
        <filter-name>UTF8Filter</filter-name>
        <filter-class>au.com.ninthavenue.web.webcore.util.UTF8Filter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>UTF8Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 

About Roger Keays

ServletRequest.setCharacterCoding() Ignored

I guess I'd call myself a problem solver. Either that, or I'm some sort of organic machine designed to convert oxygen into carbon dioxide. You could go either way on that. I'm into languages and stuff. I wrote a book. It's okay, I guess. What else? I like reading, swimming, eating, and playing music. Satisfied? Sheesh.

Leave a Comment

Please visit https://rogerkeays.com/servletrequest-setcharactercoding-ignored to add your comments.

Comment posted by: SMK, 4 months ago

Good job... Thanks.

Comment posted by: Saqib Ayub, 3 years ago

Thanks man, you made my day and saved at least a day effort

Thank you so much

Comment posted by: , 5 years ago

You can twitter me if you really have to.

Comment posted by: Nikos Maravitsas, 5 years ago

 Hi,

Great blog! Is there an email address I can contact you in private?