现在的位置: 首页 > 综合 > 正文

2、struts2类型转换

2018年02月05日 ⁄ 综合 ⁄ 共 7557字 ⁄ 字号 评论关闭

1、在login.jsp中添加一个age的text文本域,在LoginAction中新增一个int类型的成员变量,jsp提交时,将进行自动的类型转换,文本类型的age转换为int类型。

2、对于struts2来说,LoginAction每一次请求都会生成一个新的对象。

3、struts2自带了类型转换功能,8个原生数据类型、日期型、String等,struts2可以使用内建的类型转换器实现自动转换。而我们自己定义的类型,则需要我们自己定义类型转换方式了。

4、我们编写的action类,一般都要继承com.opensymphony.xwork2.ActionSupport这个父类,这个类提供了很多额外的功能支持,

5、类型转换例子剖析:

一个提交页面test.jsp:

<body>
    <h1>使用分号隔离用户与密码</h1>
    <form action="userAction.action">
    	user info:<input type="text" name="user"><br>
    	<input type="submit" value="submit">
    </form>
  </body>

我们在输入框中输入用户;密码格式的输入文本,用来代表用户和密码,在后台,我们需要将这个字符串转换为一个对象,这个对象如下:

package com.cdtax.bean;

public class User
{
	private String username;
	private String password;
	public String getUsername()
	{
		return username;
	}
	public void setUsername(String username)
	{
		this.username = username;
	}
	public String getPassword()
	{
		return password;
	}
	public void setPassword(String password)
	{
		this.password = password;
	}
	
}

jsp页面提交的action为:

package com.cdtax.struts2;

import com.cdtax.bean.User;
import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport
{
	private User user;

	public User getUser()
	{
		return user;
	}

	public void setUser(User user)
	{
		this.user = user;
	}
	
	@Override
	public String execute() throws Exception
	{
		System.out.println("username:" + user.getUsername());
		System.out.println("password:" + user.getPassword());
		return SUCCESS;
	}
}

我们看到在这个action中(UserAction)使用的是User对象,这就需要jsp页面在提交表单后,在进入UserAction之前需要进行转换,将页面表单提交的字符串格式用户;密码转换为User对象,具体使用哪个处理类来进行转换,怎么转换,需要在UserAction这个类的相同包下创建一个属性文件,名字为UserAction-conversion.properties,它的内容为字符串键值对,这里是:user=com.cdtax.converter.UserConverter,这个键值对指出UserAction类中的user成员变量使用com.cdtax.converter.UserConverter这个转换器进行类型转换。这个属性文件的名字是固定的,Xxx--conversion.properties,Xxx为相应的action类。

转换器如下:

package com.cdtax.converter;

import java.lang.reflect.Member;
import java.util.Map;
import java.util.StringTokenizer;

import com.cdtax.bean.User;

import ognl.DefaultTypeConverter;

public class UserConverter extends DefaultTypeConverter
{
	@Override
	public Object convertValue(Map context, Object value, Class toType)
	{
		if(User.class == toType) //从页面向后台对象转换
		{
			String[] str = (String[])value;
			
			String firstValue = str[0];
			
			StringTokenizer st = new StringTokenizer(firstValue,";");
			
			String username = st.nextToken();
			String password = st.nextToken();
			
			User user = new User();
			
			user.setUsername(username);
			user.setPassword(password);
			return user;
		}
		
		return null;
	}
}

我们自己定义的转换器要继承ognl.DefaultTypeConverter,提供了类型转换功能,主要是一个public Object convertValue(Map context, Object value, Class toType)方法,其中参数Object value只要转换的值,如这里是从jsp提交到后台,从字符串转换为User对象,value就是jsp传来的字符串值(实际上是字符串数组),Class toType参数指明要转换为什么类型,这里是User类型,就是User.class。

对于自定义的类型转换器来说需要提供3个信息:Action的名字、Action中待转换的属性名以及该属性对应的类型转换器。其中Action的名字是通过属性文件名来获得的,Action中待转换的属性名是通过属性文件中的key来获得的,该属性对应的类型转换器是通过该key所对应的value来获得的。

完善的UserConverter

package com.cdtax.converter;

import java.lang.reflect.Member;
import java.util.Map;
import java.util.StringTokenizer;

import com.cdtax.bean.User;

import ognl.DefaultTypeConverter;

public class UserConverter extends DefaultTypeConverter
{
	@Override
	public Object convertValue(Map context, Object value, Class toType)
	{
		if(User.class == toType) //从页面向后台对象转换
		{
			String[] str = (String[])value;
			
			String firstValue = str[0];
			
			StringTokenizer st = new StringTokenizer(firstValue,";");
			
			String username = st.nextToken();
			String password = st.nextToken();
			
			User user = new User();
			
			user.setUsername(username);
			user.setPassword(password);
			return user;
		}
		else if(String.class == toType) //从后台对象向页面转换
		{
			User user = (User)value;
			
			String username = user.getUsername();
			String password = user.getPassword();
			
			String userInfo = "username:" + username + ",password:" + password;
			
			return userInfo;
		}
		
		return null;
	}
	
}

最终的success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'success.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
     <s:property value="user" />
  </body>
</html>

注意这里引用了struts的标签库,开始使用struts标签:taglib prefix="s" uri="/struts-tags"

6、以上是一种默认的类型转换模式,struts自带的类型转换模式,struts提供了自已的一套类型转换机制

struts提供了自己的类型转换器基类:org.apache.struts2.util.StrutsTypeConverter,提供了三个方法:
convertFromString(Map context, String[] values, Class toClass)   从页面转换为后台对象
convertToString(Map context, Object o)    从后台对象转换为页面字符串
convertValue(Map context, Object o, Class toClass)
StrutsTypeConverter的源代码实现:

public abstract class StrutsTypeConverter extends DefaultTypeConverter {
    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);
        }
    }

使用struts2框架自带的类型转换器简化类型转换代码的编写:

package com.cdtax.converter;

import java.util.Map;
import java.util.StringTokenizer;

import org.apache.struts2.util.StrutsTypeConverter;

import com.cdtax.bean.User;

public class UserConverter2 extends StrutsTypeConverter
{
	@Override
	public Object convertFromString(Map context, String[] values, Class toClass)
	{
		User user = new User();
		
		String value = values[0];
		
		StringTokenizer st = new StringTokenizer(value,";");
		
		user.setUsername(st.nextToken());
		user.setPassword(st.nextToken());
		
		return user;
	}
	@Override
	public String convertToString(Map context, Object o)
	{
		 User user = (User)o;
		 
		 String username = user.getUsername();
		 String password = user.getPassword();
		 
		 String userInfo = "username:" + username + ",password:::" + password;
		 
		 return userInfo;
	}
}

同时修改UserAction-conversion.properties属性文件:user=com.cdtax.converter.UserConverter2

 7、传递一个文本框数组:

<body>
    <h1>使用分号隔离用户与密码</h1>
    <form action="userAction2.action">
    	user info 1:<input type="text" name="user"><br>
    	user info 2:<input type="text" name="user"><br>
    	user info 3:<input type="text" name="user"><br>
    	user info 4:<input type="text" name="user"><br>
    	<input type="submit" value="submit">
    </form>
  </body>

新建UserAction2:

package com.cdtax.struts2;

import java.util.List;

import com.cdtax.bean.User;
import com.opensymphony.xwork2.ActionSupport;

public class UserAction2 extends ActionSupport
{
	private List<User> user;

	public List<User> getUser()
	{
		return user;
	}

	public void setUser(List<User> user)
	{
		this.user = user;
	}
	
	@Override
	public String execute() throws Exception
	{
		return SUCCESS;
	}
}

创建新的转转器:

package com.cdtax.converter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.struts2.util.StrutsTypeConverter;

import com.cdtax.bean.User;

public class UserConverter3 extends StrutsTypeConverter
{

	@Override
	public Object convertFromString(Map context, String[] values, Class toClass)
	{
		 List<User> list = new ArrayList<User>();
		 for(String value : values)
		 {
			 StringTokenizer st = new StringTokenizer(value,";");
			 
			 User user = new User();
			 
			 user.setUsername(st.nextToken());
			 user.setPassword(st.nextToken());
			 
			 list.add(user);
		 }
		 return list;
	}

	@Override
	public String convertToString(Map context, Object o)
	{
		 List<User> list = (List<User>)o;
		 StringBuffer buffer = new StringBuffer();
		 
		 for(User user : list)
		 {
			 String username = user.getUsername();
			 String password = user.getPassword();
			 
			 buffer.append("username :  ").append(username).append(",password:  ").append(password);
			 
		 }
		 return buffer.toString();
	}

}

创建新的属性文件UserAction2-conversion.properties:

user=com.cdtax.converter.UserConverter3

8、全局类型转换

不管哪一个action,只要有User类,就使用这个转换器。而上面所讲的转换器是针对某一个特定的action来说的,可以叫做局部类型转换

对于全局类型转换,要在src目录下新建文件:xwork-conversion.properties

com.cdtax.bean.User=com.cdtax.converter.UserConverter2

它的key是要被转换的类,value是转换器类名字

 

 

 

抱歉!评论已关闭.