Question

I'm new to Jersey, and would like to change what the following produces:

@Produces(MediaType.APPLICATION_JSON)

What I'm ultimately trying to do is ensure that the character encoding of the response is set to UTF-8. I can do this on a case by case basis if i do this on every method that produces json.

@Produces("application/json;charset=UTF-8")

I'd of course like to do this once in my app, and have it just work everywhere. My first thought was to implement a java filter to modify this, and I haven't been able to get that to work.

EDIT: So to be 100% clear - I want to do this once in my app, in some global way, and have it affect all output that would be produced by Jersey for wherever I have a @Produces(MediaType.APPLICATION_JSON) in my code. So if I had 100 methods that had @Produces(MediaType.APPLICATION_JSON) on them, then suddenly 100 methods would now send with the content encoding UTF-8.

So is there anyway I can just replace what @Produces(MediaType.APPLICATION_JSON) produces? I'd just change MediaType.APPLICATION_JSON to my new value if it wasn't final ;-)

Was it helpful?

Solution

You can implement this as a ContainerResponseFilter that kind of overrides the behaviour of the @Produces annnotation in the particular case you're interested in.

@Provider
@Priority(Priorities.HEADER_DECORATOR)
public class MediaTypeFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        for (Annotation annotation : responseContext.getEntityAnnotations()) {
            filterProducesAnnotation(annotation, responseContext);
        }
    }

    private void filterProducesAnnotation(Annotation annotation, ContainerResponseContext responseContext) {
        if (annotation instanceof Produces) {
            Produces produces = (Produces) annotation;
            filterMediaTypes(produces, responseContext);
        }
    }

    private void filterMediaTypes(Produces produces, ContainerResponseContext responseContext) {
        List<Object> mediaTypes = new ArrayList<Object>();
        for (String mediaType : produces.value()) {
            contentTypes.add(mediaType.equals(MediaType.APPLICATION_JSON) ? mediaType + ";charset=UTF-8" : mediaType);
        }
        responseContext.getHeaders().put("Content-Type", mediaTypes);
    }
}

Just make sure to register the MediaTypeFilterwith your Jersey Application.

OTHER TIPS

I do not think that there is a default media type that has the character encoding you want.

Although an alternative to a filter could be to introduce a constant that contains your desired mimetype + character encoding. So something as simple as:

private static final String APPLICATION_JSON_UTF8 = MediaType.APPLICATION_JSON + ";charset=UTF-8";

The only reason for this is so that the "application/json;charset=UTF-8" isn't polluting your code as plain text (imagine refactoring if you need to change the character encoding with the 'magic string' everywhere :) )

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top