首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Seam学习(十二)-国际化跟主题

2012-09-23 
Seam学习(十二)-----国际化和主题Seam通过提供几个内置部件来为UI提供多语言支持,从而使构建国际化的应用

Seam学习(十二)-----国际化和主题
   Seam通过提供几个内置部件来为UI提供多语言支持,从而使构建国际化的应用程序变得十分容易。
  14.1. 本地化
每一个用户登录会话都有一个相关的 java.util.Locale 实例(以名为 locale 的组件形式提供给应用程序)。 一般情况下,不需要做任何特别的配置设置locale,Seam 委托JSF来判断当前的活动locale:

如果HTTP请求中有一个相关联的locale(浏览器的locale),并且这个locale在 faces-config.xml 的支持列表中,那么其他会话也使用该locale。
否则,如果在 faces-config.xml 指定了默认的locale, 那么其他会话也使用该locale。
否则,使用服务器的默认locale。
通过Seam的以下几个配置属性来手工设置locale也是你 可能的: org.jboss.seam.international.localeSelector.language、 org.jboss.seam.international.localeSelector.country和 org.jboss.seam.international.localeSelector.variant,但是并不推荐这种做法。

然而,允许用户通过应用程序的用户界面来手工设置locale也是很有益处的。Seam提供了内置的功能来覆盖通过上述算法决定的locale。你所要做的只是 在JSP或Facelet的Form中增加以下代码段:

<h:selectOneMenu value="#{localeSelector.language}">
    <f:selectItem itemLabel="English" itemValue="en"/>
    <f:selectItem itemLabel="Deutsch" itemValue="de"/>
    <f:selectItem itemLabel="Francais" itemValue="fr"/>
</h:selectOneMenu>
<h:commandButton action="#{localeSelector.select}" value="#{messages['ChangeLanguage']}"/>
或者,如果你想要一个 faces-config.xml 支持的所有locale的列表,就用:

<h:selectOneMenu value="#{localeSelector.localeString}">
    <f:selectItems value="#{localeSelector.supportedLocales}"/>
</h:selectOneMenu>
<h:commandButton action="#{localeSelector.select}" value="#{messages['ChangeLanguage']}"/>
当在下拉列表中选择一项,并按下按钮后,随后会话中Seam和JSF的locale就被刷新了。

  14.2. 标签
  JSF 通过使用 <f:loadBundle /> 来支持用户界面标签和描述文本的国际化。这个方法同样可以用在Seam应用程序中。 或者,可以利用Seam的 messages 组件用内嵌的EL表达式来显示模板标签。

14.2.1. 定义标签
Seam提供了一个 java.util.ResourceBundle (以org.jboss.seam.core.resourceBundle 的名字提供给应用程序)。 你需要通过这个指定的资源包来使你的国际化标签可用。默认情况下,Seam 使用名为messages的资源包, 你需要在 messages.properties、messages_en.properties、messages_en_AU.properties 等文件中定义你的标签。这些文件通常在 WEB-INF/classes 目录下。

因此,在 messages_en.properties中:

Hello=Hello
和在 messages_en_AU.properties中:

Hello=G'day
你可以通过设置Seam的配置属性 org.jboss.seam.core.resourceLoader.bundleNames 为资源包选择一个不同的名字。 甚至可以指定一个资源包名称列表,以深度优先进行消息的搜索。

<core:resource-loader>
    <core:bundle-names>
        <value>mycompany_messages</value>
        <value>standard_messages</value>      
    </core:bundle-names>
</core:resource-loader>
如果想为一个特殊页定义消息,可在以一个和JSF View id同名的资源包中指定,去掉前置 / 和文件扩展名。 这样,如果我们只想在 /welcome/hello.jsp 中显示消息,就把它置于 welcome/hello_en.properties 中。

你还可以在 pages.xml 中指定一个显式的绑定名称:

<page view-id="/welcome/hello.jsp" bundle="HelloMessages"/>
这样,我们就可以在 /welcome/hello.jsp 中使用定义在 HelloMessages.properties 中的消息了。

14.2.2. 标签显示
如果使用Seam的资源包来定义标签,就不用每页再写 <f:loadBundle ... /> 了,可以使用这种简单的形式:

<h:outputText value="#{messages['Hello']}"/>
或者:

<h:outputText value="#{messages.Hello}"/>
更好的一点是,message自身可以包含EL表达式:

Hello=Hello, #{user.firstName} #{user.lastName}
Hello=G'day, #{user.firstName}
你也可以在代码中这样使用消息:

@In private Map<String, String> messages;
@In("#{messages['Hello']}") private String helloMessage;
14.2.3. Faces Messages
facesMessages 组件是一个向用户显示成功或者失败消息的非常方便的途径。 我们之前描述的功能对Faces Messages同样有效:

@Name("hello")
@Stateless
public class HelloBean implements Hello {
    @In FacesMessages facesMessages;
   
    public String sayIt() {
        facesMessages.addFromResourceBundle("Hello");
    }
}
这将根据用户的locale显示 Hello, Gavin King 或者 G'day, Gavin。

  14.3. 时区
  Seam中还有一个session范围的 java.util.Timezone 实例,叫做 org.jboss.seam.international.timezone, 和一个名为 org.jboss.seam.international.timezoneSelector 的用于设置时区的组件。默认情况下,时区取服务器的默认时区。 不幸的是,JSF规范中讲所有的日期和时间都假设是UTC 的,并且显示为UTC,除非使用 <f:convertDateTime> 明确地为其指定时区。 这是一个非常不方便的默认行为。

Seam覆写了这个行为,默认所有的日期和时间都是Seam的时区。另外,Seam提供了 <s:convertDateTime> 标签,用来处理Seam 时区的转化。

  14.4. 主题
  Seam应用程序可以很方便地改变皮肤。Theme API和本地化API非常相似,但是它们二者的关注点截然不同,一些应用同时支持本地化和主题。

首先,配置所支持的主题集合:

<theme:theme-selector cookie-enabled="true">
    <theme:available-themes>
        <value>default</value>
        <value>accessible</value>
        <value>printable</value>
    </theme:available-themes>
</theme:theme-selector>
注意,第一个是默认的主题。

主题定义在一个和该主题同名的属性文件中。例如,default 主题定义在default.properties中。 default.properties可能是这样定义的:

css ../screen.css
template /template.xhtml
通常主题资源包的内容是CSS样式或图片的路径和facelet模板(不像本地化资源包那样通常是文本)。

现在我们可以在JSP或者Facelet页面中使用这些内容了。例如,一个Facelet页的风格可以这样:

<link href="#{theme.css}" rel="stylesheet" type="text/css" />
或者,当页面定义在一个子目录中时可以这样:

<link href="#{facesContext.externalContext.requestContextPath}#{theme.css}"
    rel="stylesheet" type="text/css" />
最强大的是,Facelet让我们通过 <ui:composition> 把模板主题化:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    template="#{theme.template}">
正如locale选择器一样,有一个内置的主题选择器允许用户在各主题间自由地切换:

<h:selectOneMenu value="#{themeSelector.theme}">
    <f:selectItems value="#{themeSelector.themes}"/>
</h:selectOneMenu>
<h:commandButton action="#{themeSelector.select}" value="Select Theme"/>
14.5. 使用cookie保存locale和主题设置
locale选择器、主题选择器和时区选择器全都支持持久化,把参数保存到cookie中。仅需要在components.xml中设置 cookie-enabled 配置属性:

<theme:theme-selector cookie-enabled="true">
    <theme:available-themes>
        <value>default</value>
        <value>accessible</value>
        <value>printable</value>
    </theme:available-themes>
</theme:theme-selector>

<international:locale-selector cookie-enabled="true"/>

热点排行