我一直很高兴使用omnifaces'Faces.getLocale()
来获取当前登录用户使用的区域设置(这反过来从<f:view>
定义获得)。我非常喜欢从视图到客户端到系统默认语言环境的回退方法,因为它符合我的应用程序中区域设置选择的要求:
Accept-Languages
HTTP标头现在我已经开始使用JAX-RS(resteasy实现),并且发现编写一个能够为我的后端代码提供当前用户的语言环境的服务非常困难。
我无法使用Faces.getLocale()
,因为这需要{J} -J请求处理期间不存在的FacesContext
。
我不能在@Context SecurityContext
中使用@Provider
注释(这会给我用户首选的区域设置)或@Context HttpHeaders
(访问客户端区域设置),因为仅限JAX-RS当它使用提供者本身时注入那些,而不是在我的后端代码实例化类时。
我不希望使用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
有一组仅使用Faces.getLocale()
的JSF方法,但是很难维护。所以我不想传递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
}
有没有人做过类似的工作并可以分享见解?
答案 0 :(得分:0)
我知道这篇文章已经发布了一段时间,但是因为它没有被标记为已经解决,所以我在这个具体案例中找到了解决方法:
然后我更新了构造函数,以便检测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上下文中使用。
希望得到这个帮助,