I solved the problem with writing my own MessageBodyWriter , which gets the HttpHeaders injected into the constructor, which I use later when writing the response. I will include the whole class, as it is not so big.
@Produces(MediaType.APPLICATION_XML) @Provider public class JaxbPersonalizationProvider implements MessageBodyWriter<Object> { private HttpHeaders requestHeaders; private Providers providers; public JaxbPersonalizationProvider(@Context HttpHeaders requestHeaders, @Context Providers providers) { this.requestHeaders = requestHeaders; this.providers = providers; } @Override public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return type.getAnnotation(XmlRootElement.class) != null && mediaType.equals(MediaType.APPLICATION_XML_TYPE); } @Override public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return -1; } @Override public void writeTo(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { Locale locale = If.first(this.requestHeaders.getAcceptableLanguages(), Locale.US); NumberFormat formatter = NumberFormat.getNumberInstance(locale); formatter.setMaximumFractionDigits(1); Marshaller marshaller; try { JAXBContext jc = JAXBContext.newInstance(TrackInfo.class); marshaller = jc.createMarshaller(); marshaller.setAdapter(QuantityXmlAdapter.class, new QuantityXmlAdapter.Builder().locale(locale).build()); marshaller.setAdapter(NumberPersonalizedXmlAdapter.class, new NumberPersonalizedXmlAdapter.Builder() .formatter(formatter).build()); marshaller.marshal(t, entityStream); } catch (JAXBException e) { throw new RuntimeException(e); } } }
Creates this xml fragment with the default locale en-US:
<display lang="en_US"> <value>3,286.1</value> </display>
and this xml snippet when the fr-FR locale is sent in headers:
<display lang="fr_FR"> <value>3 286,1</value> </display>
This approach is still not ideal, since now I will need to write a similar MessageBodyWriter for JSON or add JSON support for this MessageBodyWriter. In addition, I assume that JAXB providers by default make some settings that I do not use.