笔者不建议在Action中使用Set集合属性,因为Set集合里元素处于无序状态,所以Struts 2不能准确地将请求参数转换成Set元素。不仅如此,由于Set集合里元素的无序性,所以Struts 2也不能准确读取Set集合里的元素。
除非Set集合里的元素有一个标识属性,这个标识属性可以唯一地表示集合元素,这样Struts 2就可以根据该标识属性来存取集合元素了。
程序清单:codes\04\4.1\SetSupport\WEB-INF\src\org\crazyit\app\action\LoginAction.java
public class LoginAction extends ActionSupport
{
//user属性的setter和getter方法
//省略birth属性的setter和getter方法
//没有提供execute()方法,
//将直接使用ActionSupport的execute()方法
}
上面LoginAction的users属性的类型是Set,为了让Struts 2能将请求参数转换成Set集合对象,我们提供如下类型转换器。
程序清单:codes\04\4.1\SetSupport\WEB-INF\src\org\crazyit\app\converter\UserConverter.java
public class UserConverter extends StrutsTypeConverter
{
//创建一个User实例
//只处理请求参数数组第一个数组元素,
//并将该字符串以英文逗号分割成两个字符串
//为User实例的属性赋值
//将User实例添加到Set集合中
//如果待转换对象的类型是Set
}
上面的粗体字代码实现了将字符串数组转换成Set集合的转换处理。除此之外,为了让Struts 2能准确地存取Set集合元素,我们还必须让Sturts 2明白Set集合元素的标识属性,指定Struts 2根据该标识属性来存取Set集合元素。
本应用中users属性所包含的集合元素为User类,该类的代码如下。
程序清单:codes\04\4.1\SetSupport\WEB-INF\src\org\crazyit\app\domain\User.java
public class User
{
//省略name和pass的setter和getter方法
//待比较的两个对象是同一个对象,直接返回true
//只有当obj是User对象
//两个对象的name属性相等即认为二者相等
//根据name属性来计算hashCode
}
从User类的粗体字代码(重写了equals和hashCode两个方法)可以看出,该User类的标识属性是name,当两个User的name相等时即可认为它们相等。
Struts 2允许通过局部类型转换文件来指定Set集合元素的标识属性,在局部类型转换文件中增加如下一行即可指定Set集合元素的标识属性。
KeyProperty_<SetPropName>=<keyPropName>
将上面的<SetPropName>替换成集合属性名,将<keyPropName>替换成集合元素的标识属性即可。由于本应用的局部类型转换文件还需要指出Set集合元素的类型,所以该局部类型转换文件的代码如下。
程序清单:codes\04\4.1\SetSupport\WEB-INF\src\org\crazyit\app\action\LoginAction-conversion.properties
#指定users属性的类型转换器是lee.UserConverter
users=lee.UserConverter
#指定users集合属性里集合元素的索引属性是name
KeyProperty_users=name
一旦指定了集合元素的索引属性后,Struts 2就可以通过该索引属性来存取Set集合元素了。下面是在JSP页面中通过索引属性直接访问Set元素的代码片段。
<!-- 访问user集合属性里索引属性值为crazyit.org的元素的name属性-->
用户crazyit.org的用户名为:<s:property value="users('crazyit.org').name"/><br/>
<!-- 访问user集合属性里索引属性值为crazyit.org的元素的pass属性-->
用户crazyit.org的密码为:<s:property value="users('crazyit.org').pass"/><br/>
<!-- 访问user集合属性里索引属性值为b的元素的name属性-->
用户b的用户名为:<s:property value="users('b').name"/><br/>
<!-- 访问user集合属性里索引属性值为b的元素的pass属性-->
用户b的密码为:<s:property value="users('b').pass"/><br/>
生日为:<s:property value="birth"/><br/>
通过代码可以看出,直接访问Set元素的方式是:<SetPropName>('<indexPropValue>')——该方式访问的是索引属性为指定值的集合元素。上面代码将会输出Set属性里的两个User实例的name和pass,前提是这两个User实例的标识属性(name属性)值分别为scott和yeeku。
注意:
上面访问Set元素用的是圆括号,而不是方括号。但对于数组、List和Map属性,则通过方括号来访问指定集合元素。
本文转自fkJava李刚 51CTO博客,原文链接: http://blog.51cto.com/javaligang/874468,如需转载请自行联系原作者