Home | All Posts

[29 May 2011] Jersey - "charset" in Content-Type

In working with Jersey for Rexster, the issue arose some time ago that the character set was not being established in the Content-Type of the response. Therefore, the Content-Type was being set this way:

Content-Type:application/json

as opposed to

Content-Type:application/json;charset=ISO-8859-1

While the omission of the charset did not prevent JSON from being served from Rexster, it did create some problems with certain clients that expected that value to be set. Moreover, the default charset of ISO-8859-1 created problems for some users who had unicode in their data and needed the charset established to UTF-8.

One way to solve the problem within Jersey is to append the charset programmatically into the header:

return Response.ok(resultList).header("Content-Type", "application/json;charset=UTF-8").build()

Aside from the fact that the inline coding of the Content-Type left no option for multiple output formats (as described in this Jersey Issue and the subsequentally created JAX-RS Specification ), it also isn’t a terribly elegant solution. It means that you have to ensure that every service method established has that bit of code appended to it when the response object is returned. I thought that it would be nice to centralize that functionality a bit within Rexster, attempting several solutions, until I came up with one that worked.

Rexster implements a Jersey ContainerResponseFilter. The simplified code for this filter is shown in the following:

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;

import javax.ws.rs.core.MediaType;

public class CharsetResponseFilter implements ContainerResponseFilter {

    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {

        MediaType contentType = response.getMediaType();
        response.getHttpHeaders().putSingle("Content-Type", contentType.toString() + ";charset=UTF-8");

        return response;
    }
}

This filter is then plugged into Jersey through rexster.xml. Of course, other applications using Jersey would simply add it through the configuration of the Jersey servlet or programmatically as in:

ServletAdapter jerseyAdapter = new ServletAdapter();
jerseyAdapter.addInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters", "com.my.package.MyResponseFilter");

Obviously the CharsetResponseFilter shown above is overly simplified. Rexster does some basic checks to see if the charset is already established prior to overriding the settings. This allows individual service methods to be ultimately in charge of setting that value. This is useful for Rexster Extensions where returned media types can be disparate.

Home | All Posts