The best approach is to use UTF-8 enconding all over the application so the response is not encoded differently depending of the place that handles that response.
This approach applies to:
- Tomcat 6
- Java 1.6
- MyFaces 2.1.10
- RichFaces 4.2.3-Final
The places to configure the encoding are:
- server.xml in Tomcat
It's neccesary to get Tomcat to encode GET parameters. This is done by adding the URIEncoding attribute to the HTTP connector.
<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"
.... />
- Servlet Filter
Implement a servlet filter to do the UTF-8 encoding of the requests and responses:public class SetCharacterEncodingFilter implements Filter { protected String encoding = null; protected FilterConfig filterConfig = null; protected boolean ignore = true; /** * Take this filter out of service. */ public void destroy() { this.encoding = null; this.filterConfig = null; } /** * Select and set (if specified) the character encoding to be used to * interpret request parameters for this request. * @param request The servlet request we are processing * @param result The servlet response we are creating * @param chain The filter chain we are processing * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Conditionally select and set the character encoding to be used if (ignore || (request.getCharacterEncoding() == null)) { String encoding = selectEncoding(request); if (encoding != null) request.setCharacterEncoding(encoding); } response.setContentType("text/html; charset=UTF-8"); response.setCharacterEncoding("UTF-8"); // Pass control on to the next filter chain.doFilter(request, response); } /** * Place this filter into service. * @param filterConfig The filter configuration object */ public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; this.encoding = filterConfig.getInitParameter("encoding"); String value = filterConfig.getInitParameter("ignore"); if (value == null) this.ignore = true; else if (value.equalsIgnoreCase("true")) this.ignore = true; else if (value.equalsIgnoreCase("yes")) this.ignore = true; else this.ignore = false; } /** * Select an appropriate character encoding to be used, based on the * characteristics of the current request and/or filter initialization * parameters. If no character encoding should be set, return *null. * * The default implementation unconditionally returns the value configured * by the encoding initialization parameter for this * filter. * * @param request The servlet request we are processing */ protected String selectEncoding(ServletRequest request) { return (this.encoding); } }
Then you have to reference and map that filter in web.xml:
<filter>
<filter-name>SetCharacterEncodingFilter</filter-name>
<filter-class>com.foo.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SetCharacterEncodingFilter</filter-name>
<url-pattern>*.xhtml</url-pattern>
</filter-mapping>
Here I mapped only xhtml files because I'm also encoding the responses to UTF-8, so mapping images and other resources as UTF-8 will probably generate an encoding error.
- .xhtml Files
One final step is neccesary to ensure we have coherent encoding all across the webapp.
The first line in the xhtml files must be:
Then, inside the head tag of the xhtml, add the following meta tag:
Hope this helps, comment if you have any problem using this aproach.
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- This is a lot less painful if you are using facelet templating technique; if that is the case, you'd only have to add the line mentioned above in the master template instead of in every .xhtml file.