ServletRequest.setCharacterCoding() Ignored

By , 2 April 2012, 3:57 PM

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

Roger is an active member of the JSF 2 Expert Group and is happy to be a contributor to the Java Community. He has been writing software since the age of 8 and his other interests include languages, science, travel and surfing. You can follow Roger on Twitter and Google+.

Comment posted by: Nikos Maravitsas, 11 months ago

 Hi,

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

Comment posted by: , 11 months ago

You can twitter me if you really have to.

Add a comment

Please visit http://www.NinthAvenue.com.au/servletrequest-setcharactercoding-ignored to add your comments.

Follow Ninth Avenue

Get Results With Women

Website Updates


Join The Mailing List

Subscribe to our mailing list for the latest news and announcements.

Follow Us On Twitter