2

我一直很高兴地使用omnifaces'Faces.getLocale()来获取当前登录用户使用的语言环境(这反过来又从<f:view>定义中得到)。我真的很喜欢从视图到客户端到系统默认语言环境的后备方法,因为它符合我的应用程序中语言环境选择的要求:

  1. 如果用户已登录,请使用他的语言偏好(从后端实体获得)
  2. 如果找不到用户首选项,请使用Accept-LanguagesHTTP 标头中排名最高的语言
  3. 如果此时尚未选择区域设置,请使用系统默认设置。

现在我已经开始使用 JAX-RS(resteasy 实现)并且发现很难编写一个服务来为我的后端代码提供当前用户的语言环境。

我不能使用Faces.getLocale(),因为这需要FacesContext在 JAX-RS 请求处理期间不存在的。

我不能在 a (这将给我用户首选的语言环境)或(访问客户端语言环境)中使用@Context SecurityContext注释,因为 JAX-RS 仅在使用提供程序本身时注入这些注释,而不是在我的后端代码实例化类时。@Provider@Context HttpHeaders

而且我不想在我的方法签名中乱扔Locale参数,因为几乎所有东西都需要存在语言环境。

举一个具体的例子:我有一个 vcard 生成器,它根据用户的首选语言环境生成很少的 NOTE 字段。我都可以通过 JSF/EL 调用 vcard 生成方法:

<h:commandLink action="#{vcfGenerator.forPerson(person)}" 
    value="Go" target="_blank" />

并通过 REST 服务:

@GET @Path('person/{id:[1-9][0-9]*}/vcard')
@Produces('text/vcard')
String exportVcard(@PathParam('id') Long personId, @Context HttpHeaders headers) {
    VcfGenerator exporter = Component.getInstance(VcfGenerator) as VcfGenerator

    Person person = entityManager.find(Person, personId)
    if (! person)
        return Response.noContent().build()

    def locale = headers.acceptableLanguages[0] ?: Locale.ROOT
    return exporter.generateVCF(person, locale).toString()
}

这可行(VcfGenerator有一组仅使用 JSF 的方法Faces.getLocale()),但维护起来很痛苦。因此Locale,我不想传递对象,而是想说:

Vcard generateVCF(Person person) {
    Locale activeLocale = LocaleProvider.instance().getContext(VcfGenerator.class)
    ResourceBundle bundle = ResourceBundle.getBundle("messages", activeLocale, new MyControl())
    // use bundle to construct the vcard
}

有没有人做过类似的工作并可以分享见解?

4

1 回答 1

0

我知道这已经发布了一段时间,但由于它没有被标记为已解决,这是我如何为这种特定情况找到一种解决方法:

  • 首先,我得到了一个自定义 ResourceBundle 工作,正如@BalusC 所述:http: //balusc.blogspot.fr/2010/10/internationalization-in-jsf-with-utf-8.html
  • 然后我更新了构造函数以检测当前是否正在使用 FacesContext,来自:

    public Text() {
        setParent(ResourceBundle.getBundle(BUNDLE_NAME, 
        FacesContext.getCurrentInstance().getViewRoot().getLocale(), UTF8_CONTROL));
    }
    
  • 对此:

    public Text() {
        FacesContext ctx = FacesContext.getCurrentInstance();
        setParent(ResourceBundle.getBundle(BUNDLE_NAME, 
        ctx != null ? ctx.getViewRoot().getLocale() : Locale.ENGLISH, UTF8_CONTROL));
    }
    

这现在在 JSF 和 JAX-RS 上下文中都有效。

希望这有帮助,

于 2014-04-23T14:31:50.213 回答