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>
Roger Keays is an artist, an engineer, and a student of life. He has no fixed address and has left footprints on 40-something different countries around the world. Roger is addicted to surfing. His other interests are music, psychology, languages, the proper use of semicolons, and finding good food. |