我解决了写我自己的MessageBodyWriter的问题,它收到注入到构造函数中的HttpHeaders,稍后我在写回应时使用该构造函数。我会包括整个班级,因为它不是那么大。
@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);
}
}
}
与的EN-美国默认的语言环境产生这个XML摘录:
<display lang="en_US">
<value>3,286.1</value>
</display>
这个XML片段时,FR-FR的语言环境中的头被发送:
<display lang="fr_FR">
<value>3 286,1</value>
</display>
这种方法仍然不理想,因为我现在需要为JSON编写类似的MessageBodyWriter,或者为此MessageBodyWriter添加JSON支持。此外,我假设默认的JAXB提供者正在做一些调整,我没有利用。