struts2 类型转换 (一)

一。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 用 []

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值