4.5.2 为Set集合的元素指定索引属性

笔者不建议在 Action 中使用 Set 集合属性,因为 Set 集合里的元素处于无序状态,所以Struts 2不能准确地将请求参数转换成Set元素。不仅如此,由于Set集合里元素的无序性,所以Struts 2也不能准确地读取Set集合里的元素。

除非 Set 集合里的元素有一个标识属性,这个标识属性可以唯一地标识集合元素,这样Struts 2就可以根据该标识属性来存取集合元素了。

为了更好地支持Set类型的属性,Struts 2允许指定Set集合中集合元素的key属性——该key属性可以唯一地标识该元素。假设有如下的Action类。

程序清单:codes\04\4.5\SetSupport\WEB-INF\src\org\crazyit\struts2\action\LoginAction.java

public class LoginAction implements Action
{
    private Set users;
    // 封装birth请求参数的属性
    private Date birth;
    private String tip;
    // users的setter和getter方法
    public void setUsers(Set users)
    {
          this.users = users;
    }
    public Set getUsers()
    {
          return (this.users);
    }
    // 省略其他属性的setter和getter方法
    ...
    // 处理用户请求的execute方法,直接返回success字符串
          public String execute() throws Exception
    {
          return SUCCESS;
    }
}

在上面的Action类中,包含了一个Set类型的属性,该属性没有使用泛型来限制集合元素的类型,因此应该在局部类型转换文件中指定集合元素的类型。该 Action 对应的输入页面效果如图4.13所示。

图4.13 Set类型属性的输入页面

除此之外,为了更方便地访问Set属性中的集合元素,我们需要指定集合元素的索引属性,指定集合元素的索引属性通过在局部类型转换文件中增加如下项:

KeyProperty_集合属性名=集合元素的索引属性名

上面的“集合属性名”是Action中的集合属性名,“集合元素的索引属性名”是可以唯一标识集合元素的属性名。

本应用的局部类型转换文件的代码如下:

# 指定users集合属性里集合元素类型是org.crazyit.struts2.action.User
Element_users=org.crazyit.struts2.domain.User
#指定users集合属性里集合元素的索引属性是name
KeyProperty_users=name

一旦指定了集合元素的索引属性后,就可以直接通过该索引属性值来访问该集合元素,避免了只能直接访问有序集合里元素的缺陷。

下面是在JSP页面中通过索引属性直接访问Set元素的代码片段。

<!-- 访问users集合属性里索引属性值为crazyit的元素的name属性-->
用户1的用户名为:<s:property value="users('crazyit').name"/><br />
<!-- 访问users集合属性里索引属性值为crazyit的元素的pass属性-->
用户1的密码为:<s:property value="users('crazyit').pass"/><br />
<!-- 访问users集合属性里索引属性值为abc的元素的name属性-->
用户2的用户名为:<s:property value="users('abc').name"/><br />
<!-- 访问users集合属性里索引属性值为abc的元素的pass属性-->
用户2的密码为:<s:property value="users('abc').pass"/><br />
生日为:<s:property value="birth"/><br />

通过代码可以看出,直接访问Set元素的方式是:集合属性名('索引属性值') ——通过该方式访问的是索引属性为指定值的集合元素。上面代码将会输出Set属性里的两个User实例的name和pass,前提是这两个User实例的标识属性(name属性)值分别为crazyit和abc。当用户提交请求后,将看到如图4.14所示的页面。

图4.14 通过索引属性访问Set集合元素

注意

上面访问Set元素用的是圆括号,而不是方括号。但对于数组、List和Map属性,则通过方括号来访问指定的集合元素。