users@jersey.java.net

Re: [Jersey] Locale-Sensitive MessageBodyWriter

From: Charles Overbeck <coverbec_at_pacbell.net>
Date: Thu, 27 May 2010 08:59:26 -0700 (PDT)

Hi Paul,


I'm not clear on how I would inject into the message body writer. It is what I would like to do, but I don't see how.

I am modeling my writer on the Jersey entity-provider sample, so I have something like this:

@Provider
@Produces("application/pdf")
public class PdfJAXBElementWriter implements MessageBodyWriter<JAXBElement<?>> {
...
    public void writeTo(JAXBElement<?> t, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream entityStream) throws IOException,
            WebApplicationException {
    
   // Would like to determine Accept-Language header here.
   // Generate PDF...

...

I don't think I can inject the HttpHeaders into a field, because, based on debugging and println's, it looks like my PdfJAXBElementWriter is only instantiated once total, and not once per request. Wouldn't there be synchronization issues?

I can't inject it into the writeTo method, because then I would no longer be implementing the MessageBodyWriter interface.

Am I missing something obvious here?

>>What will happen if an acceptable language is not supported?<<

I'll probably just fall back to English.

Thanks,

Charles






________________________________
From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
To: users_at_jersey.dev.java.net
Sent: Thu, May 27, 2010 12:30:45 AM
Subject: Re: [Jersey] Locale-Sensitive MessageBodyWriter

Hi Charles,

You can inject HttpHeaders and use:

  https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/core/HttpHeaders.html#getAcceptableLanguages%28%29

to obtain the Accept-Language values.

The @Produces can only be used for media types, it cannot be used to match the content language.

To match on language can use the variants support if you wish:

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

You can choose to do this in the resource method or in the message body writer, arguably the latter might better suit your needs. For the latter just be sure you set the header value before you write anything to the output stream.

What will happen if an acceptable language is not supported?

Paul.
 
On May 27, 2010, at 3:18 AM, Charles Overbeck wrote:

Hi,
>
>I'm writing my first MessageBodyWriter, one that produces PDFs. Our PDFs can be localized to various languages, so I want to use the HTTP Accept-Language header to determine the language that the PDF should be generated in.
>
>The MessageBodyWriter.writeTo() method has an HttpHeaders parameter, but it is the outbound headers, not the inbound ones.
>
>The only think I can think of is to set the Content-Language header in my annotated GET method, and then read the outbound header in my writeTo() method. It changes my resource code from this though:
>
>@GET
>@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
> public JAXBElement<InvoiceType> retrieveInvoice(@PathParam("id") Long id) {
> InvoiceType invoice = findInvoice(id);
> return OBJECT_FACTORY.createInvoice(invoice);
> }
>
>to:
>
>@Context
>protected HttpServletRequest httpRequest;
>...
>@GET
>@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON, "application/pdf"})
> public Response retrieveInvoice(@PathParam("id") Long id) {
> InvoiceType invoice = findInvoice(id);
> GenericEntity<JAXBElement<InvoiceType>> entity = new GenericEntity<JAXBElement<InvoiceType>>(
> invoice) {
> };
> return Response.status(Status.OK).entity(entity).header(HttpHeaders.CONTENT_LANGUAGE, determineContentLanguage(httpRequest).build();
> }
>
>I'm hoping I'm missing something, and that I can keep my first method, only having to change the @Produces.
>
>I'm using Jersey 1.5.1.1.
>
>
>Any help or thoughts appreciated in advance.
>
>Thanks,
>
>Charles
>