前面我们使用集合时都使用了泛型,这种泛型可以让Struts 2了解集合元素的类型,Struts 2就可通过反射来创建对应类的对象,并将这些对象添加到List中。
问题是:如果不使用泛型,Struts 2还知道使用类型转换器来处理该users属性吗?Struts 2当然不知道!但Struts 2允许开发者通过局部类型转换文件来指定集合元素的类型。类型转换文件就是一个普通的Properties(*.properties)文件,类型转换文件里提供了类型转换的相关配置信息。
将上面的Action类代码中关于users属性的泛型定义取消,修改后的Action类代码片段如下。
程序清单:codes\04\4.1\noGenericList\WEB-INF\src\org\crazyit\app\action\LoginAction.java
public class LoginAction implements Action
{
//Action类里包含一个List类型的参数
//List集合元素为User类型
private List users;
private String tip;
//users属性的setter和getter方法
public void setUsers(List users)
{
this.users = users;
}
public List getUsers()
{
return this.users;
}
//省略tip属性的setter和getter方法
...
public String execute() throws Exception
{
//在控制台输出Struts 2封装产生的List对象
System.out.println(getUsers());
//因为没有使用泛型,所以要进行强制类型转换
User firstUser = (User)getUsers().get(0);
//users属性的第一个User实例来决定控制逻辑
if (firstUser.getName().equals("crazyit.org")
&& firstUser.getPass().equals("leegang") )
{
setTip("登录成功!");
return SUCCESS;
}
else
{
setTip("登录失败!!");
return ERROR;
}
}
}
如果仅仅通过上面Action类的代码,Struts 2无法知道该Action的users属性里集合元素的类型,所以我们要通过局部类型转换文件来指定集合元素的类型。
局部类型转换文件的文件名应为ActionName-conversion.properties形式,其中ActionName是需要Action的类名,后面的-conversion.properties字符串则是固定部分。类型转换文件应该放在和Action类文件相同的位置,后面的内容还会涉及局部类型转换文件。
为了指定List集合里元素的数据类型,需要指定两个部分:
Ø List集合属性的名称。
Ø List集合里元素的类型。
通过在局部类型转换文件中指定如下key-value对即可:
Element_<ListPropName>=<ElementType>
将上面的key-value对中<ListPropName>替换成List集合属性的名称、<ElementType>替换成集合元素的类型即可。以本应用为例,我们定义了如下的局部类型转换文件:
Element_users=org.crazyit.app.domain.User
增加上面的局部类型转换文件后,系统将可以识别到users集合属性的集合元素是org.crazyit.app. domain.User类型,这样Struts 2的类型转换器又可以正常工作了。
如果对于Map类型的属性,则需要同时指定Map的key类型和value类型。为了指定Map类型属性的key类型,应该在局部类型转换文件增加如下项:
Key_<MapPropName>=<KeyType>
其中Key是固定的,<MapPropName>是Map类型属性的属性名,复合类型指定的是Map的key值的全限定类名。
为了指定Map属性里的value类型,应该在局部类型转换文件中增加如下项:
Element_<MapPropName>=<ValueType>
其中Element是固定的,<MapPropName>是Map类型属性的属性名,复合类型指定的是Map属性的value类型的全限定类名。在codes\04\4.1路径下的noGenericMap应用就是这种用法的示例。
提示:
:
|
² 通过为集合属性指定泛型。
² 通过在Action的局部类型转换文件中指定集合元素类型。