Struts2资源包和本地化示例
Struts2框架支持国际化,我们可以创建资源束属性文件以供框架使用。
Struts2 i18n经常用于使用UI标签在结果页面中基于语言环境创建标签,或者在操作类实现ValidationAware接口或者扩展ActionSupport类时显示操作消息或者错误。
Struts2框架通过I18nInterceptor
拦截器支持i18n,我们可以在请求中使用参数request_locale传递语言环境。
该拦截器是defaultStack拦截器堆栈的一部分,因此我们无需为本地化做任何事情。
但是,我们可以使用parameterName参数覆盖语言环境请求参数,我们将在示例项目中对此进行研究。
当我们传递本地化密钥时,Struts 2框架将按以下顺序在各个位置查找资源包:
{ActionClassName} .properties,它应该与Action Class放在同一程序包中。
Interface.properties(每个接口和子接口)
BaseClass.properties(一直到Object.properties)
ModelDriven的模型(如果实现了ModelDriven)
将class.package中的package.properties,然后到父包,直到根
在struts属性文件中配置的全局资源属性
拥有选项很好,但过多的选项会导致混乱。
同样,如果我们有太多要本地化的属性文件,它将在搜索密钥时增加IO成本。
我个人始终只创建包和全局属性文件,但是有时当我们需要显示特定于动作类的消息时,动作类属性文件会派上用场。
我们可以通过以下选项获取本地化的文本:
<s:property value="getText('key')"
当操作类扩展ActionSupport类时可以使用上述方法,在ActionSupport类中定义了getText()方法。
<s:text name="key">Default Text</s:text>
我们可以使用Struts文本标签来获取本地化的字符串,如果找不到该键,则将使用"默认文本"。
<s:i18n name="global"> <s:text name="key"></s:text> </s:i18n>
我们可以使用i18n标记来指定从中加载属性的资源束的位置。
在上述情况下,它将尝试从WEB-INF/classes目录的global.properties中获取键值。
如果我们知道按键的位置,那么最好使用i18n标签以获得更好的性能。
<s:textfield key="mykey" name="textfieldName"
大多数UI标签都具有key属性,我们可以使用该属性从资源包中获取本地化的文本。
让我们看一个简单的Web应用程序,其中我们使用Struts2资源包和i18n支持来生成本地化响应。
我们的最终项目将如下图所示。
对于我们的示例,我们将为fr_FR和de_DE语言环境提供本地化的文本,并具有ActionClass,程序包和全局资源包。
从上图可以看到,动作类属性文件在同一程序包中,而程序包属性文件在父程序包中。
全局资源包位于classes目录中,我们将在struts配置文件中对其进行配置。
配置文件
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Struts2Localization</display-name> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
pom.xml
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>Struts2Localization</groupId> <artifactId>Struts2Localization</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <warSourceDirectory>WebContent</warSourceDirectory> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> <finalName>${project.artifactId}</finalName> </build> <dependencies> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.15.1</version> </dependency> </dependencies> </project>
部署描述符和maven pom.xml文件很简单,用于将Web应用程序配置为使用Struts2框架。
struts.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "https://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- constant to define result path locations to project root directory --> <constant name="struts.convention.result.path" value="/"></constant> <!-- constant to define global resource bundle --> <constant name="struts.custom.i18n.resources" value="global"></constant> <package name="user" namespace="/" extends="struts-default"> <action name="home"> <result>/home.jsp</result> </action> <action name="welcome" class="com.theitroad.struts2.actions.WelcomeAction"> <interceptor-ref name="defaultStack"> <param name="i18n.parameterName">appLocale</param> </interceptor-ref> <result name="success">/welcome.jsp</result> </action> </package> </struts>
我们提供全局资源束名称作为全局名称,并将i18n拦截器语言环境请求参数覆盖到appLocale,我们将在我们的用例的请求表单参数中使用此名称。
Action类
package com.theitroad.struts2.actions; import com.opensymphony.xwork2.ActionSupport; public class WelcomeAction extends ActionSupport { @Override public String execute() { return SUCCESS; } private String username; private String address; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
动作类很简单,只有几个带有getter和setter方法的Java bean属性。
资源包
全球资源包
global.properties
#global labels global.username=User Name global.address=Address global.submit=Submit global.selectlocale=Select Locale action.welcome.thankyou=Thank You
global_fr_FR.properties
#global labels global.username=User Name (FR) global.address=Address (FR) global.submit=Submit (FR) global.selectlocale=Select Locale (FR) action.welcome.thankyou=Thank You (FR)
global_de_DE.properties
#global labels global.username=User Name (DE) global.address=Address (DE) global.submit=Submit (DE) global.selectlocale=Select Locale (DE) action.welcome.thankyou=Thank You (DE)
软件包资源包
package.properties
action.welcome.title=Welcome Page action.welcome.thankyou=Thank You!!
package_fr_FR.properties
action.welcome.title=Welcome Page (FR) action.welcome.thankyou=Thank You!! (FR)
package_de_DE.properties
action.welcome.title=Welcome Page (DE) action.welcome.thankyou=Thank You!! (DE)
动作类资源包
WelcomeAction.properties
#action specific labels action.welcome.username=User Name action.welcome.address=Address
WelcomeAction_fr_FR.properties
#action specific labels for locale fr_FR action.welcome.username=User Name (FR) action.welcome.address=Address (FR)
WelcomeAction_de_DE.properties
#action specific labels for locale de_DE action.welcome.username=User Name (DE) action.welcome.address=Address (DE)
JSP页面
home.jsp
<%@ page language="java" contentType="text/html; charset=US-ASCII" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> <title>Struts2 Localization Example</title> </head> <body> <s:form action="welcome"> <s:textfield key="global.username" name="username"></s:textfield> <s:textfield key="global.address" name="address"></s:textfield> <s:select list="{'en_US','fr_FR','de_DE'}" name="appLocale" key="global.selectlocale"></s:select> <s:submit key="global.submit" name="submit"></s:submit> </s:form> </body> </html>
如您所见,我们可以从home.jsp的选择框中提供语言环境,并且变量名称与在struts属性文件中为locale参数配置的名称相同。
welcome.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title><s:property value="getText('action.welcome.title')"</title> </head> <body> <s:property value="getText('action.welcome.username')": <s:property value="username"<br> <s:text name="action.welcome.address"></s:text>: <s:property value="address"<br> <s:i18n name="global"> <s:text name="action.welcome.thankyou"></s:text> </s:i18n> </body> </html>
welcome.jsp通过i18n,文本和属性标签显示了本地化密钥的用法。