Avoid encoding problems during Ajax call in a JSF application

Goal

To avoid charset problems in a JSF application when a specific part of the page is being updated

Description

Today I struggled against one encoding problem someone reported to me in one JSF application I have been working on. Finding out what exactly was the problem was a bit hard because the situation at stake was a bit awkward: I had one page with 2 different sections, both processed through Ajax calls (meaning one does not have impact on the other). The backing bean is the same and only the first section was causing the problem: after the Ajax call, there were problems with some characters, such as the character ‘á’ or ‘ç’. It seemed a lot like an encoding problem and so I started looking for facelet pages not containing the appropriate charset (UTF-8) or pages which had not the appropriate encoding (either because they were being wrongly copied during the build or because they were originally specified with the wrong encoding) but no success.

After a while (1 or 2 hours, actually), I found out that what was triggering the problem was one specific update expression in the update attribute of the command button I was using. More specifically, there was a request for updating any parts of the page that contained the CSS class “globally-updatable”.

After some more analysis, I realized that there was one part of the page, containing that CSS class that was showing an image through a Servlet whose implementation was using the suggestion from BalusC in this page. After looking at it, I thought that the problem could be related to that servlet and that I could not be absolutely sure what was the encoding being used on that servlet or on any other servlet after that. I also tried looking for known bugs in Primefaces related to encodings and, although I’m not sure that the problem is the same, I ended up in Primefaces forum where someone suggested using a filter to enforce the encoding.

So, the solution to my problem was exactly that: the implementation of a character encoding filter that enforces any request to be made with the necessary charset: UTF-8.

How to

Create a class in your application, such as the following:

@WebFilter(value = "/*", initParams = 
                         @WebInitParam(name = CharacterEncodingFilter.ENCODING_INIT_PARAM, 
                                       value = CharacterEncodingFilter.DEFAULT_ENCODING))
public class CharacterEncodingFilter implements Filter {

    public static final String ENCODING_INIT_PARAM = "encoding";

    public static final String DEFAULT_ENCODING = "UTF-8";

    private String encoding = DEFAULT_ENCODING;

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

    @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
	encoding = config.getInitParameter(ENCODING_INIT_PARAM);
    }
}

And, suddenly, the encoding problem was gone. Because I blame myself not to have figured this out earlier, I promised that I would try to share my situation with the rest of the world so that others may fix a similar problem sooner!

Explanations

This was the first time, in almost 10 years of JSF development that I was faced with the need to specify a servlet filter to enforce the encoding of a JSF request and fix the encoding problem someone reported. This way, the communication with the client and the server guarantees that the strings are “translated” using the appropriate encoding and that they are not converted wrongly to an unexpected charset. It took me 10 years to need this filter but now, in the future, I will definitely use it more often… 🙂

One comment

  1. Is this issue related to a known Mojarra implementation?

    https://java.net/jira/browse/JAVASERVERFACES-2177

    If it is so, then some other solutions might include:

    1. Using myfaces implementation
    2. Specify request encoding as UTF-8 on tomcat/JBoss/glassfish
    3. Use a patched version of jsf.js or an updated Mojarra implementation

    From the three solutions I would prefer solution 3 because:

    1. It doesnt require forcing the request encoding on every request
    2. It doesnt require global configuration changes on the servlet container
    3. It solves the problema at it’s roots

    The filter should maybe check for the request being an ajax call before changing the parameter encoding…

    Best
    JP

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s