Struts2对国际化提供了非常好的支持,它对Java的国际化实现方式做了一个封装,以提供更友好、更便利的国际化实现。
一、Struts2资源包(文件)的组织和加载方式(顺序)
在查找一个消息字符串时,Struts2将按照下面的顺序搜索资源包:
1)查找与调用与Action类同名的资源文件(与Action类在同一个包中),如:LoginAction,则LoginAction.properties。
2)查找所有与Action类的基类同名的资源文件,直到Object.properties。(位置是否也是跟类在同一包中?)
3)查找所有与Action类实现的接口同名的资源文件。
4)如果Action实现了ModelDriven接口,则Struts2会调用getModel()方法获得模型对象,然后以模型对象所属的类进行层次的查找,这将送步骤1)开始重复。
5)查找类所在的包和父包中的package.properties,直到顶层包。
6)查找I18N消息key本身的层次关系,如:user.label.username,如果user是Action类的某个属性,则以该属性所属的类,在它的类层次中查找key为label.username的消息字符串,与前面步骤一样。
7)查找默认的资源包,在struts.properties或者struts.xml中,通过struts.custom.i18n.resources属性来设置默认的资源包,如:struts.custom.i18n.resources=org.struts2.ApplicationResources,即在org.struts2包下的ApplicationResources资源包(省略了.properties)
二、在消息文本中使用参数
Struts2提供了两种在消息文本中设置参数的方式:
1)沿袭了Java中设置消息文本参数的方式,即从{0}到{9}的占位符(结合MessageFormat类的format方法来格式化消息字符串),该方式可以看成是被动地接受值。
2)在消息文本中使用OGNL表达式,语法格式:${expr},可以让其主动获取Action、session等中的值。
greeting=${username},欢迎访问! 资源文件配置。
<s:text name="greeting" />页面标签,其中${username}将从对应得作用域内取值。
三、访问国际化消息
Struts2提供了多种方式来访问资源文件中的本地化消息,以适应不同的应用场景,主要分为:
1)在action中访问本地化消息:让action类继承ActionSupport(而不是实现Action接口),在ActionSupport提供了多个重载的getText()方法,用于访问资源文件中的本地化信息!
2)在JSP页面中访问本地化消息:Struts2提供了text标签,用于在JSP页面中访问本地化消息,可以通过param标签嵌套来设置参数
<s:text name="greeting">
<s:param value="'张三'"/> //替换占位符{0},似乎字符串要带引号
</s:text>
3)在表单标签的属性中访问本地化消息:因Struts2标签的属性可以使用OGNL表达式,且OGNL表达式又支持对类中的方法进行调用,所以在需要访问本地化消息时,如果在值栈中存在着从ActionSupport类继承的action类的实例时,可以使用getText方法来获取资源文件中的消息字符串了。
<s:textfield name="user.username" label="%{getText('username')}" /> //因label默认不支持ognl解析,所以加%{}
<s:textfield name="user.username" key="username" /> 专门的key属性配置
4)在资源文件中访问本地化消息:在资源文件中引用其它的本地化消息
email=邮件地址
error.email.invalid=${getText("email")}格式错误
四、错误信息的国际化
还是通过ActionSupport对国际化支持的方法来实现,即addFieldError方法
一般在Action的catch中写:
addFieldError("user.username",getText("error.username.exist"));//如此则通过<s:fielderror/>标签可以打印出错误信息,而如果页面中有user.username的<s:textfield name="user.username" key="username" /> (在xhtml主题下的表单标签可以自动输出与其名字相同的字段错误信息)则其也会输出对应的错误信息。
return INPUT;
五、Struts2设定访问用户的locale的流程
当访问Web程序时,如何知道应该显示哪一个语言版本呢?
1)提供一个语言选择首页(通常用英文显示)
2)由程序根据浏览器发送的请求头(Accept-Language)中的语言信息来自动选择一种语言版本,同时在页面中也向用户提供选择其他语言的功能,以便用户查看其他语言版本。
Struts2在设定访问用户的locale时,按照下列的步骤来进行。
1)判断struts.locale属性(在struts.properties或struts.xml中设置)是否有值,如果有,则将这个值转换为Locale对象并保存到ActionContext中。
2)如果没有设置struts.locale属性,则从浏览器发送的请求报头中获取语言信息,并创建Locale保存到ActionContext中。
3)com.opensymphony.xwork2.interceptor.I18nInterceptor拦截器(在dufaultStack中)获取名为request_locale请求参数的值,如果这个值存在,则以这个值创建一个Locale对象,然后将这个对象作为session的属性(属性名为:WWW_TRANS_I18N_LOCALE),保存到session中,同时也保存到ActionContext中。
PS:注意只有访问action才有上面的完整的3步骤,访问jsp不会有步骤3,因为不会拦截jsp页面,所以一般都是通过action转发给jsp页面的
得:
1)默认locale通过struts.locale配置
2)修改locale只需提交名为request_locale的请求参数