internationalization - 我如何 i18n JAX-RS (Jersey) JAXB 注释响应

标签 internationalization jaxb jersey jax-rs

我们在从 Web API 返回的模型对象上使用 JAXB 注释,我们希望数据本地化,并根据用户偏好(即指标与法规)格式化其他值。我们通过向 Marshaller 添加自定义适配器来做到这一点。

Marshaller marshaller = jc.createMarshaller();
marshaller.setAdapter(NumberPersonalizedXmlAdapter.class,
          new NumberPersonalizedXmlAdapter(locale);
marshaller.marshal(expected, writer);

尝试最简单的方法,我将只从 HTTP 请求 header 中获取区域设置,并将其提供给 MessageBodyWriter 类之一中的 Marshaller。

我查看了扩展默认注册的提供程序,如 XMLRootElementProvider,但意识到它们大多是最终编写的,所以我放弃了这种方法。无论如何,我至少需要扩展 10 个类,所以这并不理想。

有谁知道如何最好地让 MessageBodyWriter 中的编码器与每个请求的客户适配器一起设置?我很确定它与ContextResolver有关.

最佳答案

为编码编写 ContextResolver 会产生比编写 MessageBodyWriter 更清晰、更合适的解决方案。所有 JAXB 类都使用 Providers.getContextResolver获取编码器的方法。我提供了我的自定义 ContextResolver 并且我有 i18n 响应。

@Provider
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public class JaxbPersonalizerContextResolver implements ContextResolver<Marshaller> {

    private HttpHeaders requestHeaders;

    public JaxbPersonalizerContextResolver(@Context HttpHeaders requestHeaders) {
        this.requestHeaders = requestHeaders;
    }

    @Override
    public Marshaller getContext(Class<?> type) {
        Locale locale = If.first(this.requestHeaders.
                                    getAcceptableLanguages(), Locale.US);
        NumberFormat formatter = NumberFormat.getNumberInstance(locale);
        formatter.setMaximumFractionDigits(1);

        Marshaller marshaller;
        try {
            JAXBContext jc = JAXBContext.newInstance(type);
            marshaller = jc.createMarshaller();
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
        marshaller.setAdapter(QuantityXmlAdapter.class, 
                           new QuantityXmlAdapter.Builder().locale(locale).build());
        marshaller.setAdapter(NumberPersonalizedXmlAdapter.class,
                new NumberPersonalizedXmlAdapter.Builder().
                                    formatter(formatter).build());
        return marshaller;
    }
}

JSON 没有被本地化,经过一些调查,我意识到正在使用 Jackson JSON 库,而不是与 Jersey 库一起分发的 JAXBJSONElementProvider。我removed the POJOMappingFeature configuration在 web.xml 中,我已经本地化了 JSON,但是,它不如 Jackson JSON 好。

一个非常干净的解决方案,让我觉得 JAX-RS 和 Jersey 实现做得很好。

关于internationalization - 我如何 i18n JAX-RS (Jersey) JAXB 注释响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8944025/

相关文章:

ruby-on-rails - Rails i18n - 翻译带有链接的文本

Django 与 i18n 的 react

spring - 创建一个JAXB Unmarshaller池

java - 如何在JAVA中使用JAXB正确生成XML

google-chrome - 如何在所有Google(国际)页面上加载内容脚本?

apache-flex - Flex 程序翻译中的复数形式

xml - 独立值不会出现在 moxy - jaxb 生成的 xml 中

java - 使用 Jersey 防止对象属性内的空值

jersey - 如何将 JSON 请求发布到 Jersey REST 服务?

GenericType jersey 客户端中的 java.util.List.<init>()