一。struts2 内建的类型转换器。
对于大部分的常用类型,开发者根本无需创建自己的类型转换器,
因为struts2可以完成大多数常用的类型转换。这些常用的类型转换
是通过struts2内建的类型转换器完成的,struts2已经内建了字符串
类型和如下类型之间的类型转换器。
boolean和Boolean : 完成字符串和布尔值之间的转换。
char和Character: 完成字符串和字符之间的转换。
int和Integer: 完成字符串和整型值之间的转化。
long和Long: 完成字符串和长整型值之间的转换。
float和Float: 完成字符串和单精度浮点值之间的转换。
double和Double: 完成字符串和双精度浮点值之间的转换。
Date: 完成字符串和日期类型之间的转换,日期格式使用用户请求所在Locale的SHORT格式。
数组: 在默认情况下,数组元素是字符串,如果用户提供了自定义的类型转换器,也可以是其他符合类型的数组。
集合: 在默认情况下,假定集合元素类型为String,并创建一个新的ArrayList封装所有的字符串。
二。基于 OGNL 的类型转换。
struts2 内建了 OGNl 表达式,可以方便的将我们在页面上输入的字符串数据转换成JavaBean中的Boolean,Float,Integer,Double,Long等数据类型,在无法转换成功时,还可以给出错误提示,非常方便
首先简历JavaBean:
public class User {
private String username;
private Integer password;
private String[] books;
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getPassword() {
return password;
}
public void setPassword(Integer password) {
this.password = password;
}
}
编写Action,需要继承ActionSupport,在action中有两个变量,一个是User类,一个是birth属性
我们定义birth属性和user类中的password属性都必须是Integer类型
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
private String tip;
private User user;
private Integer birth;
public Integer getBirth() {
return birth;
}
public void setBirth(Integer birth) {
this.birth = birth;
}
public String execute() throws Exception {
System.out.println(this.getUser().getUsername());
System.out.println(this.getUser().getPassword());
return SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getTip() {
return tip;
}
public void setTip(String tip) {
this.tip = tip;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
struts.xml (WEB-INF/classes下)
<?xml version="1.0" encoding="GBK" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="struts" extends="struts-default"> <action name="Login" class="HelloWorld.LoginAction"> <result name="input">/helloworld/index.jsp</result> <result name="success">/helloworld/welcome.jsp</result> <result name="error">/helloworld/error.jsp</result> </action> </package> </struts>
struts.properties(WEB-INF/classes下)
struts.custom.i18n.resources=messageResource
信息录入页面:
<%@ page language="java" contentType="text/html; charset=gb2312"
pageEncoding="gb2312"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title></title>
</head>
<body>
<div style="color:red">
<s:fielderror />
</div>
<s:form action="Login">
<s:textfield name="user.username" key="username"></s:textfield>
<s:textfield name="user.password" key="password"></s:textfield>
<s:textfield name="birth" key="password"></s:textfield>
<s:submit value="login"></s:submit>
</s:form>
</body>
</html>
信息展示页面:
<%@ page language="java" contentType="text/html; charset=gb2312"
pageEncoding="gb2312"%>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title></title>
</head>
<body>
转换成功!<br>
用户1的用户名为:<s:property value="user.username"/><br>
用户1的密码为:<s:property value="user.password"/><br>
</body>
</html>
我们在资源文件中加入:
xwork.default.invalid.fieldvalue={0}类型转换错误,运行index.jsp.,在三个输入框中都输入admin,则会出现以下提示:
user.password字段类型转换失败
birth字段类型转换失败
在资源文件中定义的是全局转换错误提示的内容,如果想对具体Action中的字段进行提示,则编写ActionName.properties,本文中对应的就是LoginAction.properties,放在和Action同一个目录下,内容格式如下:invalid.fieldvalue.birth (其中birth为action中属性名)
本文LoginAction.properties内容为:invalid.fieldvalue.birth=生日必须为数字:
再次运行index.jsp.结果如下:
user.password字段类型转换失败
生日必须位数字
注意:
1. 因为 Struts2 是需要直接创建一个复合类(user 类)的实例,所以必须有无参数构造器。
2. 如果希望使用 user.name 请求参数的形式为 Action 实例的 user 属性的 name 属性赋值,则必须 user类中 提供 setName() 方法;Action 提供 setUser() 方法。
更极端的情况,我们甚至可以直接生成 Collection (List.....) 或者 Map 实例
1.map
public class MyAction extends ActionSupport{
private Map<String,User> users;
public String execute() throws Exception{
if (users.get("one").getName != null){
return INPUT;
}
return SUCCESS;
}
public Map<String, User> getUsers() {
return users;
}
public void setUsers(Map<String, User> users) {
this.users = users;
}
}
<!-- input.jsp 中可以使用下面方法,users 为 map , one 为 map 的 key -->
<input type="text" name="users['one'].name">
<s:property value="users['one'].name" />
2.List
把上面的 MyAction 总的 users 属性改成 List<User> ,我们就可以通过索引来指定请求参数转换成 List 的哪个元素。
jsp如下:
<!-- input.jsp 中可以使用下面方法,users 为 List , 0,1 为 list 的 索引 -->
<input type="text" name="users[0].name">
<s:property value="users[1].name" />
三。自定义类型转换器。
如果用户输入一个 "abc,xyz" 字符串,我们需要将其转换成一个 User 类型的实力,其中 abc 为 User 实例的 name 属性,xyz 为 User 实例的 pass 属性。
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>局部类型转换器</title>
</head>
<body>
<form action="login.action" method="post">
<table align="center" width="360">
<caption><h3>局部类型转换器</h3></caption>
<tr align="center">
<td>用户信息的用户名和密码以英文逗号隔开</td>
</tr>
<tr>
<td>请输入用户信息:<input type="text" name="user"/></td>
</tr>
<tr align="center">
<td><input type="submit" value="转换"/>
<input type="reset" value="重填" /></td>
</tr>
</table>
</form>
</body>
</html>
import com.opensymphony.xwork2.Action;
public class LoginAction implements Action
{
//使用类型转换器将字符串请求参数直接转换成一个User实例
private User user;
//封装Action处理结果的tip属性
private String tip;
//user属性的setter和getter方法
public void setUser(User user)
{
this.user = user;
}
public User getUser()
{
return (this.user);
}
//tip属性的setter和getter方法
public void setTip(String tip)
{
this.tip = tip;
}
public String getTip()
{
return (this.tip);
}
//处理用户请求的execute方法
public String execute() throws Exception
{
//直接调用user属性的name属性和pass属性进行判断
if (getUser().getName().equals("crazyit")
&& getUser().getPass().equals("leegang") )
{
setTip("转换成功");
return SUCCESS;
}
else
{
setTip("转换失败");
return ERROR;
}
}
}
public class User
{
//User类包含的两个字符串属性
private String name;
private String pass;
//无参数的构造器
public User()
{
}
//初始化全部属性的构造器
public User(String name , String pass)
{
this.name = name;
this.pass = pass;
}
//name属性的setter和getter方法
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
//pass属性的setter和getter方法
public void setPass(String pass)
{
this.pass = pass;
}
public String getPass()
{
return this.pass;
}
}
Struts2 的类型转换器是基于 OGNL , OGNL 中又一个 TypeConverter 接口,这个接口就是实现类型转换器必须实现的接口
这个接口有点复杂,所以OGNL还提供了该街接口的一个实现类 ognl.DefaultTypeConverter , 通过继承该类重写convertValue方法 ,实现自定义类型的转换 . // 这里大家可以查看ognl.jar包
方法是这样的 convertValue(Map context, Object value, Class toType)
第一个参数: context 是类型转换环境的上下文
第二个参数 : value 是须要转换的参数,方向不同,value的类型也是不同的。当把字符串类型向 User 类型转换时,value 是原始字符串数组;当需要把 User 向字符串类型转换时,value 是 User 实例。
第三个参数 : toType 是转换后的目标类型, 我们通过判断 toType 类型即可判断转换方向。当 toType 是 User 类型时,表明需要将字符串转换成 User;当 toType 是 String 类型时,表明需要把 User 实例转换成字符串类型。
返回值是 : 转换后的目标类型, 方向不同,类型也是不同的.我们把字符串向 User 转换,返回类型就是 User类型,反之亦然!
提示: DefaultTypeConverter 是通过 HttpServletRequest 的 getParameterValues(name) 方法来获取请求参数。因此获取的总是数组,如果请求参数只包含一个单个的值,则请求参数值是一个长度为 1 的字符串数组
import java.util.Map;
import ognl.DefaultTypeConverter;
//通过继承DefaultTypeConverter来实现类型转换器
public class UserConverter extends DefaultTypeConverter
{
//类型转换器必须重写convertValue方法,该方法需要完成双向转换
public Object convertValue(Map context,
Object value, Class toType)
{
//当需要将字符串向User类型转换时
if (toType == User.class )
{
//系统的请求参数是一个字符串数组
String[] params = (String[])value;
//创建一个User实例
User user = new User();
//只处理请求参数数组第一个数组元素,并将该字符串以英文逗号分割成两个字符串
String[] userValues = params[0].split(",");
//为User实例赋值
user.setName(userValues[0]);
user.setPass(userValues[1]);
//返回转换来的User实例
return user;
}
//当需要将User实例转换成字符串时
else if (toType == String.class )
{
//将需要转换的值强制类型转换为User实例
User user = (User) value;
return "<" + user.getName() + "," + user.getPass() + ">";
}
return null ;
}
}
配置有2种
1.局部类型转换器
ActionName-conversion.properties: ActionName 是需要转换生效的 Action 的类名,后面-conversion.properties 字符串是固定部分
上面内容对应的是 LoginAction-conversion.properties,内容是 user=lee.UserConverter
LoginAction-conversion.properties 文件应该与 LoginAction.class 放在相同位置。
2.全局类型转换器
import com.opensymphony.xwork2.Action;
import java.util.*;
public class LoginAction implements Action
{
//使用类型转换器将字符串请求参数直接转换成一个User实例
private User user;
//封装customer请求参数的属性
private User customer;
//封装birth请求参数的属性
private Date birth;
//封装Action处理结果的tip属性
private String tip;
//无参数的构造器
public LoginAction()
{
}
//user属性的setter和getter方法
public void setUser(User user)
{
this.user = user;
}
public User getUser()
{
return this.user;
}
//customer属性的setter和getter方法
public void setCustomer(User customer)
{
this.customer = customer;
}
public User getCustomer()
{
return this.customer;
}
//birth属性的setter和getter方法
public void setBirth(Date birth)
{
this.birth = birth;
}
public Date getBirth()
{
return this.birth;
}
//tip属性的setter和getter方法
public void setTip(String tip)
{
this.tip = tip;
}
public String getTip()
{
return this.tip;
}
//处理用户请求的execute方法
public String execute() throws Exception
{
//直接调用user属性的name属性和pass属性进行判断
if (getUser().getName().equals("crazyit")
&& getUser().getPass().equals("leegang") )
{
setTip("转换成功");
return SUCCESS;
}
else
{
setTip("转换失败");
return ERROR;
}
}
}
在上面 Action 中我们看到了 user 和 customer两个属性,这两个属性的类型都是 User,对于一个 Action 里包含两个 User 类型的情形,我们还可以使用一个局部类型转换器,但如果系统中多个 Action 都包含 User 类型的属性,则应该使用全局类型转换器。
全局类型转换器 应该提供一个 xwork-conversion.properties 文件,该文件也是 Properties 文件,其内容由多个“复合类型=对应的类型转换器” 项组成,其中“复合类型”指定需要完成类型转换的复合类,“对应的类型转换器” 指定所指定类型转换的转换器。
# 指定lee.User类的类型转换器为lee.UserConverter lee.User=lee.UserConverter
一旦注册了上面的全局类型转换器,该全局类型转换器就会对所有 User 类型属性起作用
四。基于 Struts 2 的类型转换器。
DefaultTypeConverter 必须通过 toType 参数来判断转换方向。
为了简化,struts 2 提供了 StrutsTypeConverter类:
package org.apache.struts2.util;
import java.util.Map;
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
public abstract class StrutsTypeConverter extends DefaultTypeConverter {
//重写 DefaultTypeConverter 的convertValue 方法
public Object convertValue(Map context, Object o, Class toClass) {
//复合类型转换成字符串
if (toClass.equals(String.class)) {
return convertToString(context, o);
} else if (o instanceof String[]) {//字符串转换成复合类型
return convertFromString(context, (String[]) o, toClass);
} else if (o instanceof String) {//字符串转换成复合类型
return convertFromString(context, new String[]{(String) o}, toClass);
} else {
return performFallbackConversion(context, o, toClass);
}
}
/**
* Hook to perform a fallback conversion if every default options failed. By default
* this will ask Ognl's DefaultTypeConverter (of which this class extends) to
* perform the conversion.
*
* @param context
* @param o
* @param toClass
* @return The fallback conversion
*/
protected Object performFallbackConversion(Map context, Object o, Class toClass) {
return super.convertValue(context, o, toClass);
}
/**
* Converts one or more String values to the specified class.
*
* @param context the action context
* @param values the String values to be converted, such as those submitted from an HTML form
* @param toClass the class to convert to
* @return the converted object
*/
public abstract Object convertFromString(Map context, String[] values, Class toClass);
/**
* Converts the specified object to a String.
*
* @param context the action context
* @param o the object to be converted
* @return the converted String
*/
public abstract String convertToString(Map context, Object o);
}
1. 当需要把字符串转换成复合类型时,调用 convertFromString() 抽象方法
2. 当需要把复合类型转换成字符串时,调用 convertToString() 抽象方法
实现
public class UserConverter extends StrutsTypeConverter {
// 处理将字符串类型转换成复合类型的方法
public Object convertFromString(Map context, String[] values, Class toClass) {
User user = new User();
// 只处理请求参数数组第一个数组元素,并将该字符串以英文逗号分割成两个字符串
String[] userValues = values[0].split(",");
// 为User实例赋值
user.setName(userValues[0]);
user.setPass(userValues[1]);
// 返回转换来的User实例
return user;
}
// 处理把复合类型转换成字符串类型的方法
public String convertToString(Map context, Object o) { // 将需要转换的值强制类型转换为User实例
User user = (User) o;
return "<" + user.getName() + "," + user.getClass() + ">";
}
}
五。数组属性的类型转换器
对于前面的事例,一直只处理字符串数组的第一个元素。
如果页面上包含 2 个用户信息请求参数,名称都是 user ,这 2 个请求参数必须通过 getParameterValues() 方法来获取,此时 user 请求参数必须是数组类型,或者 List 类型 ,如下:
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>数组属性的类型转换器</title>
</head>
<body>
<form action="login.action" method="post">
<table align="center" width="360">
<caption><h3>数组属性的类型转换器</h3></caption>
<tr align="center">
<td>用户信息的用户名和密码以英文逗号隔开</td>
</tr>
<tr>
<td>请输入用户1信息:<input type="text" name="users"/></td>
</tr>
<tr>
<td>请输入用户2信息:<input type="text" name="users"/></td>
</tr>
<tr>
<td>用户生日:<input type="text" name="birth"/></td>
</tr>
<tr align="center">
<td><input type="submit" value="转换"/>
<input type="reset" value="重填"/></td>
</tr>
</table>
</form>
</body>
</html>
import com.opensymphony.xwork2.Action;
import java.util.Date;
public class LoginAction implements Action
{
private User[] users;
private Date birth;
private String tip;
//无参数的构造器
public LoginAction()
{
}
//users属性的setter和getter方法
public void setUsers(User[] users)
{
this.users = users;
}
public User[] getUsers()
{
return this.users;
}
//birth属性的setter和getter方法
public void setBirth(Date birth)
{
this.birth = birth;
}
public Date getBirth()
{
return this.birth;
}
//tip属性的setter和getter方法
public void setTip(String tip)
{
this.tip = tip;
}
public String getTip()
{
return this.tip;
}
//处理请求的execute方法
public String execute() throws Exception
{
//只根据第一个数组元素判断转向逻辑
if (getUsers()[0].getName().equals("crazyit")
&& getUsers()[0].getPass().equals("leegang") )
{
setTip("转换成功");
return SUCCESS;
}
else
{
setTip("转换失败");
return ERROR;
}
}
}
上面 Action 用了 User[] 数组来封装 user 请求参数。
下面是 类型转换器代码 :
import java.util.Map;
import ognl.DefaultTypeConverter;
import org.apache.struts2.util.StrutsTypeConverter;
import java.util.List;
import java.util.ArrayList;
public class UserConverter extends StrutsTypeConverter
{
//处理将字符串类型转换成复合类型的方法
public Object convertFromString(Map context,
String[] values, Class toClass)
{
//如果请求参数数组的长度大于1
if (values.length > 1)
{
//创建一个User数组
User[] result = new User[values.length];
//遍历请求参数数组
for (int i = 0; i < values.length ; i++ )
{
//将每个数组元素转换成一个User实例
User user = new User();
String[] userValues = values[i]
.split(",");
user.setName(userValues[0]);
user.setPass(userValues[1]);
//将转换的User实例装入数组
result[i] = user;
}
return result;
}
//如果请求参数数组的长度为1
else
{
//创建一个User实例
User user = new User();
//将请求参数转换成一个User实例
String[] userValues = values[0].split(",");
user.setName(userValues[0]);
user.setPass(userValues[1]);
return user;
}
}
//处理把复合类型转换成字符串类型的方法
public String convertToString(Map context, Object o)
{
//如果需要转换的值是单个的User实例
if (o instanceof User)
{
User user = (User)o;
return "<" + user.getName() + ","
+ user.getPass() + ">";
}
//如果需要转换的值是User数组
else if (o instanceof User[])
{
User[] users = (User[])o;
String result = "[";
for (User user : users )
{
result += "<" + user.getName()
+ "," + user.getPass() + ">";
}
return result + "]";
}
else
{
return "";
}
}
}
本例完全可以替代 四。 中的例子,因为本例不仅处理了单一请求参数;也处理了多个请求参数
六。集合属性的类型转换器
五。 中的例子,可以把 users 改为 List类型
import com.opensymphony.xwork2.Action;
import java.util.Date;
import java.util.List;
public class LoginAction implements Action
{
private List<User> users;
private Date birth;
private String tip;
//无参数的构造器
public LoginAction()
{
}
//users属性的setter和getter方法
public void setUsers(List<User> users)
{
this.users = users;
}
public List<User> getUsers()
{
return this.users;
}
//birth属性的setter和getter方法
public void setBirth(Date birth)
{
this.birth = birth;
}
public Date getBirth()
{
return this.birth;
}
//tip属性的setter和getter方法
public void setTip(String tip)
{
this.tip = tip;
}
public String getTip()
{
return this.tip;
}
//处理请求的execute方法
public String execute() throws Exception
{
//只根据第一个数组元素判断转向逻辑
if (getUsers().get(0).getName().equals("crazyit")
&& getUsers().get(0).getPass().equals("leegang") )
{
setTip("转换成功");
return SUCCESS;
}
else
{
setTip("转换失败");
return ERROR;
}
}
}
import java.util.Map;
import ognl.DefaultTypeConverter;
import org.apache.struts2.util.StrutsTypeConverter;
import java.util.List;
import java.util.ArrayList;
public class UserConverter extends StrutsTypeConverter
{
//处理将字符串类型转换成复合类型的方法
public Object convertFromString(Map context,
String[] values, Class toClass)
{
//如果请求参数数组的长度大于1
if (values.length > 1)
{
//创建一个List对象,List对象的元素类型是User
List<User> result = new ArrayList<User>();;
//遍历请求参数数组
for (int i = 0; i < values.length ; i++ )
{
//将每个数组元素转换成一个User实例
User user = new User();
String[] userValues = values[i].split(",");
user.setName(userValues[0]);
user.setPass(userValues[1]);
//将转换的User实例装入List对象
result.add(user);
}
return result;
}
//如果请求参数数组的长度为1
else
{
//创建一个User实例
User user = new User();
//将请求参数转换成一个User实例
String[] userValues = values[0].split(",");
user.setName(userValues[0]);
user.setPass(userValues[1]);
return user;
}
}
//处理把复合类型转换成字符串类型的方法
public String convertToString(Map context, Object o)
{
//如果需要转换的值是单个的User实例
if (o instanceof User)
{
User user = (User)o;
return "<" + user.getName()
+ "," + user.getPass() + ">";
}
//如果需要转换的值是List对象
else if (o instanceof List)
{
List<User> users = (List<User>)o;
String result = "[";
for (User user : users )
{
result += "<" + user.getName()
+ "," + user.getPass() + ">";
}
return result + "]";
}
else
{
return "";
}
}
}
以上例子 List 必须用泛型
七。集合类型转换的高级特性
六。 中的例子,List 必须用 泛型,下面不使用泛型 :
import com.opensymphony.xwork2.Action;
import java.util.Date;
import java.util.List;
public class LoginAction implements Action
{
private List users;
private Date birth;
private String tip;
//无参数的构造器
public LoginAction()
{
}
//初始化全部属性的构造器
public LoginAction(List users , Date birth , String tip)
{
this.users = users;
this.birth = birth;
this.tip = tip;
}
//users属性的setter和getter方法
public void setUsers(List users)
{
this.users = users;
}
public List getUsers()
{
return this.users;
}
//birth属性的setter和getter方法
public void setBirth(Date birth)
{
this.birth = birth;
}
public Date getBirth()
{
return this.birth;
}
//tip属性的setter和getter方法
public void setTip(String tip)
{
this.tip = tip;
}
public String getTip()
{
return this.tip;
}
//处理请求的execute方法
public String execute() throws Exception
{
//因为取消了泛型,必须执行强制类型转换
if (((User)getUsers().get(0)).getName().equals("crazyit")
&& ((User)getUsers().get(0)).getPass().equals("leegang"))
{
setTip("转换成功");
return SUCCESS;
}
else
{
setTip("转换失败");
return ERROR;
}
}
}
<form action="login.action" method="post">
<table align="center" width="360">
<caption><h3>指定List元素类型</h3></caption>
<tr>
<td>第一个用户名:<input type="text"
name="users[0].name"/></td>
</tr>
<tr>
<td>第一个密码:<input type="text"
name="users[0].pass"/></td>
</tr>
<tr>
<td>第二个用户名:<input type="text"
name="users[1].name"/></td>
</tr>
<tr>
<td>第二个密码:<input type="text"
name="users[1].pass"/></td>
</tr>
<tr>
<td>生日:<input type="text" name="birth"/></td>
</tr>
<tr align="center">
<td><input type="submit" value="转换"/>
<input type="reset" value="重填" /></td>
</tr>
</table>
</form>
为了让系统的类型转换起作用,2 种方法:
1. 使用泛型来限制集合元素的类型
2. 使用 Struts 2 的配置文件:使用局部类型转换的配置文件来指定集合元素的数据类型。
List
LoginAction-conversion.properties
Element_users=lee.User
Element 是固定的,users 是 Action 中的集合属性名,复合类型是集合元素类型的全限定类名(lee.User--完整的包前缀)
Map
Key_xxx=key元素类型
Key 是固定的,xxx是 Action 中 Map 类型的属性名,复合类型指定 Map 属性 key 类型的全限定类名
Element_xxx=value 元素类型
Element 是固定的,xxx是 Action 中 Map 类型的属性名,复合类型指定 Map 属性 value类型的全限定类名
八。set 集合元素指定索引属性
因为 Set 是无序集合 ,Struts 2 不能准确读取。
为了更好的支持 set ,Struts 2 允许指定 set 集合中集合元素的 key是属性 ---该 key 可以唯一标识该元素。
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
import java.util.Set;
public class LoginAction extends ActionSupport
{
//Set类型的集合属性
private Set users;
private Date birth;
private String tip;
//无参数的构造器
public LoginAction()
{
}
//users属性的setter和getter方法
public void setUsers(Set users)
{
this.users = users;
}
public Set getUsers()
{
return this.users;
}
//birth属性的setter和getter方法
public void setBirth(Date birth)
{
this.birth = birth;
}
public Date getBirth()
{
return this.birth;
}
//tip属性的setter和getter方法
public void setTip(String tip)
{
this.tip = tip;
}
public String getTip()
{
return this.tip;
}
public String execute() throws Exception
{
return SUCCESS;
}
}
上面 Action 有一个 set ,没用泛型。
<form action="login.action" method="post">
<table align="center" width="360">
<caption><h3>Set属性的类型转换</h3></caption>
<tr align="center">
<td>用户信息的用户名和密码以英文逗号隔开</td>
</tr>
<tr>
<td>请输入用户1信息:<input type="text" name="users"/></td>
</tr>
<tr>
<td>请输入用户2信息:<input type="text" name="users"/></td>
</tr>
<tr>
<td>用户生日:<input type="text" name="birth"/></td>
</tr>
<tr align="center">
<td><input type="submit" value="转换"/>
<input type="reset" value="重填"/></td>
</tr>
</table>
</form>
在 set 中指定索引属性
LoginAction-conversion.properties
#指定 users 集合属性里集合元素类型是lee.User Element_users=lee.User #指定 users 集合属性里集合元素的索引属性是 name KeyProperty_users=name
在 jsp 中 获取数据
转换成功!<br />
<!-- 访问user集合属性里索引属性值为scott的元素的name属性-->
用户1的用户名为:<s:property value="user('crazyit').name"/><br />
<!-- 访问user集合属性里索引属性值为scott的元素的pass属性-->
用户1的密码为:<s:property value="user('crazyit').pass"/><br />
<!-- 访问user集合属性里索引属性值为abc的元素的name属性-->
用户2的用户名为:<s:property value="user('abc').name"/><br />
<!-- 访问user集合属性里索引属性值为abc的元素的pass属性-->
用户2的密码为:<s:property value="user('abc').pass"/><br />
生日为:<s:property value="birth"/><br />
直接方法 set 元素:集合属性('索引属性值'),上面实例 2 个 user 实例的 name 属性分别是 crazyit 和 abc。
注意: Set 元素用的是() 。数组,list,map 用 []