国际化
资源文件和资源包
要用Struts实现国际化和本地化,首先要定义资源文件的名称,这个文件会包含用默认语言编写的会在程序中出现的所有消息。这些消息以”键-值“对的形式存储,如下:
error.validation.localtion = The entered location is invalid
当对一个应用程序进行国际化处理时,所要用的各种语言版本的”标签“信息应该存放在不同的属性文件中,每一个这样的文件对应一种语言版本。所有属性文件合在一起称为资源包(Resource Bundle)。属性文件的命名格式可分为以下两种:a)文件名前缀.properties
b) 文件名前缀 _ 语言种类 .properties文件名后缀必须是 properties,前缀可自由书写,其中语言种类字段必须是有效的ISO语言代码。
配置国际化步骤
(一般只需要步骤1,2)
1、 准备资源文件
2 、在struts.xml中使用struts.custom.i18n.resources常量即可加载全局资源文件(一般这样配置就够了)
<constant name="struts.custom.i18n.resources"
value="cn.itcast.i18n.resource" />
resource为资源文件的基本名。
3、在jsp页面获取国际化的资源文件的信息
方法一:使用text标签:用来显示一条国际化消息的数据标签. 相当于从property
标签调用 getText 方法. 该标签包含如下属性:
* name: 用来检索消息的键
* var:用来引用压入 ContextMap 栈的值的变量名
* 可以通过 param 子标签向 text 标签传递参数
<s:textname="item.username"/>
方法二:使用ognl表达式
可以使用 property 标签或是使用某个表单标签的 label属性, 来显示一条调用 getText()
方法而得到的本地消息:
<s:textfieldname="username" label="%{getText('item.username')}"/>
<s:propertyvalue="%{getText('item.username')}"/>
4、JSP中直接访问某个资源文件
i18n 标签:用来加载一个自定义的ResourceBundle.不用做任何配置
name: 将被加载的资源集的java完全限定名
<s:i18nname=“resource">
<s:textname=“item.username”/>
</s:i18n>
resource为类路径下资源文件的基本名。
如果要访问的资源文件在类路径的某个包下,可以这样访问:
<s:i18n name=“cn.itcast.i18n.resource">
<s:textname=“item.test">
<s:param>小张</s:param>
</s:text>
</s:i18n>
上面访问cn.itcast.i18n包下基本名为resource的资源文件。
OGNL表达式
#号的用法
用法1:访问OGNL上下文和Action上下文,#相当ActionContext.getContext()
1、 如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,
需要添加#前缀。
2、OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack
(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略
#命名对象,直接访问该对象的属性即可。
用法2:集合的投影(过滤)
1、集合的投影(只输出部分属性)
collectionName.{ expression}
2、集合的过滤
1) 集合的过滤有以下三种方式:
a.“?#”:过滤所有符合条件的集合,如:users.{?#this.age > 19};
b.“^#”:过滤第一个符合条件的元素,如:users.{^#this.age > 19};
c.“$#”:过滤最后一个符合条件的元素,如:users.{$#this.age > 19} 。
.2)this 表示集合中的元素;3、集合的投影和过滤
投影(过滤)操作返回的是一个集合,可以使用索引取得集合中指定的
元素,如:users.{?#this.age > 19}[0]
用法3:构造Map,如#{‘foo1’:‘bar1’, ‘foo2’:‘bar2’}。
这种方式常用在给radio或select、checkbox等标签赋值上
%的用法
“%”符号的用途是在标签的属性值被理解为字符串类型时,告诉执行环境%{}里的是OGNL表达式。
{ }中值用 ’ ’引起来,这是不再是ogle表达式,而是普通的字符串
$的用法
“$”有两个主要的用途
* 用于在国际化资源文件中,引用OGNL表达式
* 在Struts2配置文件中,引用OGNL表达式
标签介绍
property标签
property标签用于输出指定值:
<s:propertyvalue=“#name" default="a defaultvalue" />
*default:可选属性,如果需要输出的属性值为null,则显示该属性指定的值
* escape:可选属性,指定是否格式化HTML代码。
* value: 可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输
出ValueStack栈顶的值。
set标签
set标签用于将某个值放入指定范围。
var:变量的名字,name,id和var表达的含义是一样的,name,id被var替代
scope:指定变量被放置的范围,该属性可以接受application、session、request、page或
action。如果没有设置该属性,则默认放置在action中。
value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。
push标签
push:将对象放入栈顶,不能放入其他范围,当标签结束,会从栈顶删除。
value:要push到堆栈中的值 。
action标签
Action:通过指定命名空间和action名称,该标签允许在jsp页面直接调用Action
name:action名字(不包括后缀,如.action)
namespace:action所在命名空间
executeResult:Action的result是否需要被执行,默认值是false不执行
iterator标签
Iterator:标签用于对集合进行迭代,这里的集合包含List、Set和数组。
value:可选属性,指定被迭代的集合,如果没有设置该属性,则使用ValueStack栈顶的集合。
var: 可选属性,引用变量的名称.
status:可选属性,该属性指定迭代时的IteratorStatus实例。该实例包含如下几个方法:
intgetCount(),返回当前迭代了几个元素。
intgetIndex(),返回当前迭代元素的索引。
booleanisEven(),返回当前被迭代元素的索引是否是偶数
booleanisOdd(),返回当前被迭代元素的索引是否是奇数
booleanisFirst(),返回当前被迭代元素是否是第一个元素。
booleanisLast(),返回当前被迭代元素是否是最后一个元素。
url标签
url:该标签用于创建url,可以通过"param"标签提供request参数.
value:如果不提供就用当前action,使用value后缀必须加.action
action:用来生成url的action,如果没有则使用value
namespace :命名空间
var:引用变量的名称.
模型驱动
1、使用模型驱动必须实现 ModelDriven<T> ,T表示模型驱动的对象
* private Customer customer = new Customer();
public Customer getModel() {
return customer;
}
2、注意:实现获取页面表单值,并且表单的值与模型驱动对象的属性值要对应
3、获取值用getXXX,赋值setXXX
4、表单回显
* 第一种方法:回显
/**此时设置值必须是一个模型驱动中对象,对模型驱动中的栈顶对象赋值*/
this.customer.setUsername("张三");
this.customer.setPsw("123");
this.customer.setTel("88886666");
* 第二种方法:回显
/**将实例化对象放置到栈顶*/
Customer c = new Customer();
c.setUsername("李四");
c.setPsw("123456");
c.setTel("66668888");
ValueStack stack = ServletActionContext.getContext().getValueStack();
stack.pop();
stack.push(c);
token,控制表单重复提交
1、javaweb表单重复提交* 在保存的jsp中定义一个隐藏域:<input type="hidden" name="token.html" value="XsdfsdfsdY23dsf">* 第一次点击“保存”时,将隐藏域的值放到session中session.setAttribute("tokenxyz",XsdfsdfsdY23dsf);* 原理表单重复提交:* 在同一个页面:第二次点击“保存”的时候,后台通过名称token.html获取隐藏域的值XsdfsdfsdY23dsf ----(1)* 同时获取session中的值session.getAttribute("tokenxyz"); ----(2)* 对比:* 如果(1)==(2)表单重复提交
2、struts2的表单重复提交(1):在add.jsp中添加<s:token/>(注意:<s:token/>一定要当到form表单中)(2):在struts.xml的配置文件中将,添加token拦截器(因为token拦截器在默认栈没有执行)在<package></package>中添加<interceptors><interceptor-stack name="tokenStack"><interceptor-ref name="defaultStack"></interceptor-ref><!-- 将token拦截器放置到默认栈的后面 --><interceptor-ref name="token"><!-- 针对Action中某个方法控制表单重复提交 ,需要添加includeMethods,指定Action的方法,如果是多个方法用逗号分开--><param name="includeMethods">save</param></interceptor-ref></interceptor-stack></interceptors><default-interceptor-ref name="tokenStack"></default-interceptor-ref>(3):如果表单重复提交,提交到message.jsp中,告诉使用者表单重复提交在message.jsp中,要想提示struts2表单重复提交信息,需要添加<s:actionerror/>(4):将重复提交的信息显示自定义的中文信息,key的目录为struts2-core-2.1.8.1.jar,org.apache.struts2.struts-message.properties:自定义创建token.properties文件,内容为:struts.messages.invalid.token=\u60A8\u7684\u8868\u5355\u5DF2\u7ECF\u91CD\u590D\u63D0\u4EA4\u4E86\uFF0C\u8BF7\u4E0D\u8981\u518D\u641E\u7834\u574F\uFF01在struts.xml文件加载token.properties文件:代码如下:<constant name="struts.custom.i18n.resources" value="fileupload,cn.itcast.web.i_i18n.resource,cn.itcast.web.l_model.token"></constant>