我一直很高兴地使用omnifaces'Faces.getLocale()
来获取当前登录用户使用的语言环境(这反过来又从<f:view>
定义中得到)。我真的很喜欢从视图到客户端到系统默认语言环境的后备方法,因为它符合我的应用程序中语言环境选择的要求:
- 如果用户已登录,请使用他的语言偏好(从后端实体获得)
- 如果找不到用户首选项,请使用
Accept-Languages
HTTP 标头中排名最高的语言 - 如果此时尚未选择区域设置,请使用系统默认设置。
现在我已经开始使用 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
}
有没有人做过类似的工作并可以分享见解?