users@jersey.java.net

Re: [Jersey] Jersey and Charsets

From: Paul Sandoz <Paul.Sandoz_at_oracle.com>
Date: Tue, 10 Aug 2010 12:06:34 +0200

On Aug 10, 2010, at 2:46 AM, Charles Overbeck wrote:

> Hello,
>
> I'm trying to understand Jersey and charsets. I'm using Jersey
> 1.1.5.1, with JAXB and mainly the default Jersey classes for
> generating XML and JSON responses, as well as my own
> MessageBodyWriter that generates PDFs.
>
> 1) In my tests, the XML and JSON responses are always UTF-8 encoded.
> That's actually the encoding I want. However, the charset is not set
> in the Content-Type in the HTTP header. For example, for JSON it
> reads "Content-Type: application/json". I think it should ideally be
> "Content-Type: application/json; charset=UTF-8". How will a client
> know the charset otherwise? Or is JSON always UTF-8? The XML
> responses don't have the charset either, but I guess that doesn't
> really matter, as the encoding is in the XML prolog. Still, it seems
> like that would be nice too.
>

Yes, Jersey always defaults to UTF-8 but does not set explicitly set
the charset parameter (strictly speaking it should).

One can also explicitly set the charset in media type of the @Produces.

Any character-based support in Jersey, JAXB/String etc. will obey the
charset parameter of the content-type (in the request or response to
be produced).


> 2) I don't need to do this, but in researching this, I couldn't get
> my Jersey app to return anything not in UTF-8 encoding. I'm curious
> why not, and maybe the answer will help me understand things. For
> example, if I send an HTTP header "Accept-Charset: UTF-16", the
> response still comes back in UTF-8. How do I set up my app to create
> responses in different encodings? Or how do I make the HTTP request
> so as to get back the data in a different encoding?
>
> To my knowledge I'm doing fairly vanilla stuff. Here's a snippet
> from one of my resource files:
>
> @Path("{id: [0-9]+}")
> @GET
> @Produces({MediaType.APPLICATION_XML,
> MediaType.APPLICATION_JSON, "application/pdf"})
> public JAXBElement<InvoiceType> retrieveInvoice(@PathParam("id")
> Long id) throws MyException {
> // Just return a JAXBElement<InvoiceType>, and let
> MessageBodyWriters do the rest...
>

If you need to do anything other than media type conneg then you have
to do it yourself using the Request.selectVariant.

   https://jsr311.dev.java.net/nonav/releases/1.1/javax/ws/rs/core/Request.html
#selectVariant%28java.util.List%29

You can create a list of variants for the media types and charsets
that are supported by the server and the most acceptable variant will
be selected. That list of variants can be statically created so it
does not need to have a per-request cost.


One thing i have yet to resolve is the obtaining of the most
acceptable media type selected when the resource method is invoked. We
have an issue open for this. If this could be obtained then you can
create variants just for the charset. Then select on those. Then add
the charset to the most acceptable media type. That way you reduce
need to duplication and the extra dimension of the media type.

Paul.