实现在 JSF 和 JAX-RS 中工作的区域设置提供程序

2024-01-05

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

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

现在我开始使用 JAX-RS(resteasy 实现),并发现编写一个为我的后端代码提供当前用户区域设置的服务非常困难。

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

我无法使用@Context SecurityContext中的注释@Provider(这会给我用户首选的区域设置)或@Context HttpHeaders(访问客户端区域设置)因为 JAX-RS 仅在使用提供程序本身时注入这些内容,而不是在我的后端代码实例化该类时注入。

我不想乱扔我的方法签名Locale参数,因为实际上一切需要存在语言环境。

举一个具体的例子:我有一个 vcard 生成器,它根据用户的首选区域设置生成小注释字段。我可以通过 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
}

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


我知道这已经发布了一段时间,但由于它尚未被标记为已解决,因此我如何找到针对此特定情况的解决方法:

  • 首先,我得到了一个自定义的 ResourceBundle,正如 @BalusC 所描述的:http://balusc.blogspot.fr/2010/10/internationalization-in-jsf-with-utf-8.html 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));
    }
    
  • To This:

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

现在,这可以在 JSF 和 JAX-RS 上下文中运行。

希望这有帮助,

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实现在 JSF 和 JAX-RS 中工作的区域设置提供程序 的相关文章

随机推荐