image - JSF 2.0 应用程序中的本地化图像

标签 image jsf localization jsf-2

我有一个 JSF 2.0 应用程序,它允许用户更改网站的语言,这会影响文本和图像。

当前区域设置是在 session bean 中设置的,每个页面都具有从此 session 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,它从用户 session 中检索区域设置。结果,它正确地创建了一个指向“/resources/english/img/flag.gif”的资源实例。然后用户将他/她的区域设置更改为法语。重新加载页面时,将呈现并请求相同的图像 URL。这次 ViewHandler.calculateLocale() 将 Locale.FRENCH 返回给 ResourceHandler,这会导致创建路径为 "/resources/french/img/flag.gif" 的资源。

在流式传输图像之前,根据规范,ResourceHandler.handleResourceRequest() 必须执行以下操作:

•Call Resource.userAgentNeedsUpdate(javax.faces.context.FacesContext). If this method returns false, HttpServletRequest.SC_NOT_MODIFIED must be passed to HttpServletResponse.setStatus(), then handleResourceRequest must immediately return.

它检测到自上次浏览器请求以来资源未更新 - 没有考虑到对该“逻辑”URL 的先前请求导致服务器上不同的“物理”资源。并返回 HTTP 304,这会导致之前的英文图像再次显示给用户。

如果使用 Shift+F5 刷新页面,则可以正确下载法语图像,因为用户代理没有发送“If-Modified-Since”。

始终可以在库名称中使用 EL 手动添加区域设置前缀,如下所示:

<h:graphicImage library="#{userContext.locale}/img" name="flag.gif" />

但我仍然认为前一种方法应该有效并且更干净。

我想知道:

  1. 如果我们使用“name”和“library”属性,为什么 JSF 不生成图像的实际路径“src”? JSF 拥有在初始页面请求上构建完整路径的所有信息 - 包括 UIViewRoot 中的区域设置(无需实现我自己的 ViewHandler)。我的假设是,这是因为根据规范资源也可以放在类路径中的 JAR 中。不过,servlet 的 url 只能用于检索类路径定位的资源,而无法为其提供直接 url。

  2. 为什么规范规定生成的图像“src”属性应包含库,但没有提及区域设置前缀(请参阅 Resource.getReqestPath())?图像 src 通过 Resource.getRequestPath() 检索。如果前缀包含在 URL 中,法语和英语图像将不会被浏览器解释为单个“已修改”资源。

欢迎任何想法!

最佳答案

实际上,您也可以使用常规 HTML <img>标记并构建您自己的路径。
看来最好创建自己的 Controller 来解析路径:

<img alt="#{i18n['some.image.title']}" src="#{localizationController.someImage}" />

本地化 Controller 可以像这样读取上下文路径(当前应用程序的基本 URL):

String basePath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();

ExternalContext还提供真实路径名(即磁盘上的路径名,如果您使用分解格式) - 请参阅getRealPath()方法,如果您需要的话。

为什么我更喜欢这种方法?它非常简单且非常强大:人们不仅可以使用本地化 Controller 来提供本地化对象的路径,例如 CSS 文件(或至少主样式表覆盖)、客户端脚本,当然还有图像,而且还可以实际提供动态本地化上下文(即 JavaScript 中的可翻译字符串数组)。

回答您的具体问题:

  1. 简短的回答是我不知道。我很乐意考虑设计此 API 的人仔细权衡所有优点和缺点并选择最佳解决方案(尽管不能满足所有可能的用例)。

  2. 对此我可以给你准确的答案。基本上,正确的国际化应用程序不应包含任何可能依赖于区域设置的图像,即特定于文化的图像。这是相当理想主义的世界观,但说实话,具有实际上取决于语言环境的图像应该是罕见的情况。
    如果我理解您的具体问题,您想根据当前的区域设置切换一些特定的国家/地区标志。事实上,您也可以在此处使用条件渲染 ( render="#{someController.someBooleanMethod}" ),并实际上一次写入所有图像引用。我知道这很糟糕,但这是一种可行的解决方案。

关于image - JSF 2.0 应用程序中的本地化图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7036741/

相关文章:

jsf - 在 Setter 之前调用的事件函数

c# - 将 1 位图像转换为 8 位图像

java - 如何在 GWT 中将图像插入超链接

linux - 体积图像数据的分布式处理

javascript - 使用带有变量的javascript更改图像src

java - 考虑 GWT 中的本地化,将字符串格式化为日期

java - Eclipse + Maven + JavaServer Faces -> ClassNotFoundException : StartupServletContextListener

java - Ajax 渲染属性在 h :dataTable in JSF2 中不起作用

xcode - 本地化无法读取字符串文件 (Xcode 6.3.2)

python - 我可以使用 GAE + python 2.7 + django.utils.translation 吗?