国际化:使程序在不做任何修改的情况下,就可以使用在不同的语言环境中。
i18n(Internationalization)
国际化最重要的就是资源文件,在运行是对资源文件的内容调用,而资源文件作用范围有:
- 全局范围
- 包范围
- action范围
struts2中国际化实现简单实例:(先贴代码,后面分析)
1、test.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" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<a href="${pageContext.request.contextPath }/test/lan.action?request_locale=zh_CN">中文</a>
<a href="${pageContext.request.contextPath }/test/lan.action?request_locale=en_US">English</a>
<s:form action="test/some" method="post">
<s:textfield name="name" key="test.form.name"></s:textfield>
<s:textfield name="password" key="test.form.password"></s:textfield>
<s:submit key="test.form.submit"></s:submit>
</s:form>
</body>
</html>
2、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" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<s:text name="welcome.text.msg">
<s:param><s:property value="name"/></s:param>
</s:text>
${sessionScope.msg}<br>
</body>
</html>
3、struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="my"></constant>
<package name="test" namespace="/test" extends="struts-default" >
<action name="some" class="com.test2.loginAction" >
<result>/welcome.jsp</result>
</action>
<action name="lan">
<result>/test.jsp</result>
</action>
</package>
</struts>
4、loginAction.java
public class loginAction extends ActionSupport {
private String name;
private int password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPassword() {
return password;
}
public void setPassword(int password) {
this.password = password;
}
public String execute(){
// String message = this.getText("action.login.message");
String[] args = {name};
String message = this.getText("action.login.message",args);
ActionContext.getContext().getSession().put("msg", message);
System.out.println("loginAction");
return "success";
}
}
5、全局资源文件my_en_US.properties
test.form.name=name
test.form.password=password
test.form.submit=login
action.login.message=System!{0}
welcome.text.msg=welcome!{0}
6、全局资源文件
test.form.name=\u59D3\u540D
test.form.password=\u5BC6\u7801
test.form.submit=\u767B\u5F55
action.login.message=\u7CFB\u7EDF{0}
welcome.text.msg=\u6B22\u8FCE{0}
因为东西太杂,以一个总体代码展示,以下详细解析:
1、先以正常的方式写一个简单表单:
<form action="test/some" method="post">
name : <input name="name" type="text"><br>
password: <input name="password" type="text"><br>
<input type="submit" value="submit">
</form>
- 这里面的name,password,submit在现实时是需要国际化的,于是编写对应的资源文件。
- 文件内容是键值对,这里的key都是任意的,内容则是对应着需要国际化的内容。
- 有多少种语言就写几种资源文件。
2、在struts2中对资源文件内容的引用要通过< s:>标签来实现,所以将需要国际化的内容都转换成此标签对应的内容:(这里的key就是资源文件中定义key值)
<s:form action="test/some" method="post">
<s:textfield name="name" key="test.form.name"></s:textfield>
<s:textfield name="password" key="test.form.password"></s:textfield>
<s:submit key="test.form.submit"></s:submit>
</s:form>
3、对于资源文件,全局范围的资源文件:
- 命名随意,但一般以xxx_en_US.propertis这种形式
- 需要在struts.xml中注册
- 注册后默认读取的资源就是这个全局资源文件
4、于是再进行资源文件注册(给struts.custom.i18n.resources常量赋值,资源文件名因为前面有一样的命名内容,所以可以省略后面的,让struts2自动匹配)
<constant name="struts.custom.i18n.resources" value="my"></constant>
5、最后要实现在转换语言时,为了能调用相应的资源文件,就需要通过action来实现。
在默认的Action Support类中,会执行默认拦截器栈(里面有i18n拦截器)。
所以就在struts.xml中注册处理国际化请求的action(action Support是默认执行的action,可以省略)
<action name="lan">
<result>/test.jsp</result>
</action>
6、在页面添加国际化请求:
<a href="${pageContext.request.contextPath }/test/lan.action?request_locale=zh_CN">中文</a>
<a href="${pageContext.request.contextPath }/test/lan.action?request_locale=en_US">English</a>
在action请求后要加request_locale参数并赋值,这个参数在i18n拦截器中定义着(可看源码)
到这里就实现了简单的静态页面国际化,当国际化的内容里有动态参数时,需要为动态参数添加占位符:
action.login.message=System!{0}
welcome.text.msg=welcome!{0}
action.login.message=System!{0}这里的动态参数赋值,在action方法中进行,如:
// String message = this.getText("action.login.message");调用资源文件对应的静态值
String[] args = {name};//将name放入String数值中
String message = this.getText("action.login.message",args);//为资源文件的占位符赋值并取出value
ActionContext.getContext().getSession().put("msg", message);//将取出的内容放入Session中,以便跳转页面中调用显示数据
welcome.text.msg=welcome!{0}中动态参数的赋值在jsp页面中进行:
<s:text name="welcome.text.msg">
<s:param><s:property value="name"/></s:param>
</s:text>
包范围资源文件
- 命名如:package_en_US.properties,package是规定的
- 命名被规范,所以不用注册
- 在进去相应的包内才会获取该资源,如执行action时取该包范围资源
- 放在包下
action范围资源文件
- 命名如:Action类名_en_US.properties
- 命名被规范,所以不用注册
- 在执行相应的action才会获取该资源
- 放在action包对应包下
这些资源文件,会按范围缩小,相互覆盖
在jsp中可以自定义使用资源文件
<s:i18n name="my"></s:i18n>//这里name赋值资源路径
//将国际化的标签,包含进来
<s:form action="test/some" method="post">
<s:textfield name="name" key="test.form.name"></s:textfield>
<s:textfield name="password" key="test.form.password"></s:textfield>
<s:submit key="test.form.submit"></s:submit>
</s:form>
<s:i18n name="com/test2/loginAction"></s:i18n>