【发布时间】:2011-10-25 14:09:47
【问题描述】:
我有一个 JSF 2.0 应用程序,它允许用户更改应该影响文本和图像的站点语言。
当前区域设置是在会话 bean 中设置的,并且每个页面都具有从该会话 bean 设置的区域设置。它适用于文本。但是我对图像有问题。目前我们正在使用这样的图像:
<h:graphicImage name="flag.gif" library="img">
这导致生成以下 HTML 代码返回给用户代理:
<img src="/AppRoot/faces/javax.faces.resource/flag.gif?ln=img" .... />
假设用户请求英文页面。上图的 GET 请求由 ResourceHandler.handleResourceRequest() 处理。它使用 ViewHandler.calculateLocale() 来识别正确的语言环境前缀。我已经使用从用户会话中检索语言环境的 calculateLocale() 实现了我自己的 ViewHandler。结果,它正确地创建了一个指向 "/resources/english/img/flag.gif" 的资源实例。然后用户将他/她的语言环境更改为法语。重新加载页面时,会呈现并请求相同的图像 URL。这一次 ViewHandler.calculateLocale() 将 Locale.FRENCH 返回给 ResourceHandler,从而创建路径为 "/resources/french/img/flag.gif" 的资源。
在流式传输图像之前,根据规范,ResourceHandler.handleResourceRequest() 必须执行以下操作:
•调用 Resource.userAgentNeedsUpdate(javax.faces.context.FacesContext)。如果此方法返回 false,则必须将 HttpServletRequest.SC_NOT_MODIFIED 传递给 HttpServletResponse.setStatus(),然后 handleResourceRequest 必须立即返回。
它检测到资源自上次浏览器请求以来没有更新 - 没有考虑到先前对该“逻辑” URL 的请求导致服务器上的不同“物理”资源。并返回 HTTP 304 导致之前的英文图像再次显示给用户。
如果使用 Shift+F5 刷新页面,则由于用户代理未发送“If-Modified-Since”,因此正确下载了法国图像。
总是可以在库名称中手动添加语言环境前缀,如下所示:
<h:graphicImage library="#{userContext.locale}/img" name="flag.gif" />
但我仍然认为前一种方法应该有效并且更清洁。
我想知道:
如果我们为 . JSF 具有在初始页面请求上构建完整路径的所有信息 - 包括 UIViewRoot 的语言环境(无需实现我自己的 ViewHandler)。我的假设是,这是因为根据规范,资源也可以放在类路径中的 JAR 中。 servlet 的 url 仍然可以仅用于检索无法提供直接 url 的位于类路径的资源。
为什么规范声明生成的图像“src”属性应该包含库,但没有说明语言环境前缀(参见 Resource.getReqestPath())? Image src 由 Resource.getRequestPath() 检索。如果前缀包含在 URL 中,则法语和英语图像不会被浏览器解释为单个“已修改”资源。
欢迎提出任何想法!
【问题讨论】:
标签: image jsf localization jsf-2