users@jersey.java.net

[Jersey] Re: Using filter to always set charset=UTF-8 on response

From: Sekhar Vajjhala <sekharv01_at_gmail.com>
Date: Mon, 14 Nov 2011 11:46:54 -0500

Here are a couple of other possible alternatives to writing a response
Filter.

1. Use a package level annotation for associating a charset with a media
type;
   the charset can be generated for the media type specified in @Produces
   annotation.

   For e.g. the annotations could look something like:

   ------
   File: CharSet.java
   /*
    * Define an annotation for media type whose format is:
    * media-type = type "/" subtype *( ";" parameter )
    */
    @Target(ElementType.PACKAGE)
    public @interface CharSet {
        String mediatype();
        String mediasubtype();
        String charset();
    }

    ------
    File: MediaTypes.java
    @Target(ElementType.PACKAGE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MediaTypes {
        CharSet[] charset();
    }

    -------
    File: package-info.java
    @CharSets(
        {CharSet {mediatype="application", mediasubtype="xml",
charset="UTF-8")
    }
    package com.examples;

2. If a charset can be associated with a media type, JAX-RS implementation
   can explicitly generate the default charset in the Content-Type as Paul
   pointed out in his email thread you pointed to. This approach would
   follow recommendation for e.g. laid out in RFC 3023 XML Media Types
   http://tools.ietf.org/html/rfc3023 which
   states the following:

      Although listed as an optional parameter, the use of the charset
      parameter is STRONGLY RECOMMENDED, since this information can be
      used by XML processors to determine authoritatively the charset of
      the XML MIME entity.

   But (from my reading of HTTP 1.1 spec), it appears that some HTTP 1.0
   clients did not deal properly if charset was explicitly present. So,
   if charset is generated by default, then there needs to be a way
   to turn it off for dealing with such clients.

Of the above two a package level annotation is preferrable.

Sekhar Vajjhala

On Thu, Nov 10, 2011 at 3:26 PM, <eirik.lygre_at_gmail.com> wrote:

> I need to set charset=UTF-8 on all responses from my jersey endpoints.
> I've googled a lot, and in search of a configurable solution, it seems
> that using a response filter is the way to go.
>
> In
> http://jersey.576304.n2.nabble.com/Jersey-and-Charsets-tp5392069p541144
> 3.html, Paul Sandoz showed the conceptual idea of how this should work:
>
> > Perhaps the best way you can add the charset is to write a response
> filter to modify the
> > content-type for certain values rather than modifying all your
> annotations.
> >
> > ContainerResponse response;
> >
> > MediaType m = response.getMediaType();
> > if (/ charset not present on m and m requires a charset) {
> > // create a new media type adding a charset of UTF-8.
> > m = ...
> > response.getHttpHeaders().putSingle("Content-Type", m);
> > }
>
> I ended up doing pretty much this:
>
> public class UTF8ResponseFilter implements ContainerResponseFilter
> {
> private static Map<String, String> charset =
> Collections.singletonMap("charset", "UTF-8");
>
> @Override
> public ContainerResponse filter(ContainerRequest request,
> ContainerResponse response) {
> MediaType oldType = response.getMediaType();
> MediaType newType = new MediaType(oldType.getType(),
> oldType.getSubtype(), charset);
> response.getHttpHeaders().putSingle("Content-Type",
> newType);
> return response;
> }
> }
>
> My single question, then, is this:
>
> -> Is this best practice for setting charset on all responses?
>
> Eirik
>