Struts2资源包和本地化示例

时间:2020-02-23 14:36:06  来源:igfitidea点击:

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,文本和属性标签显示了本地化密钥的用法。