struts2-类型转换

概述

从一个 HTML 表单到一个 Action 对象, 类型转换是从字符串到非字符串.
  •HTTP 没有 “类型” 的概念. 每一项表单输入只可能是一个字符串或一个字符串数组. 在服务器端, 必须把 String 转换为特定的数据类型
在 struts2 中, 把请求参数映射到 action 属性的工作由 Parameters 拦截器负责, 它是默认的 defaultStack 拦截器中的一员. Parameters 拦截器可以自动完成字符串和基本数据类型之间转换. 
 
接收请求参数
  a) 利用之前学过的知识,接收请求参数
  1 HttpServletRequest req = ServletActionContext.getRequest();
  2 String userName = req.getParameter("userName");

   b) 采用基本类型接收请求参数

    在Action类中定义与请求参数同名的属性,struts2便能通过反射技术自动接收请求参数并赋予给同名属性。

public class UserAction extends ActionSupport {
      private Integer id;
      private String userName
      //struts2通过反射技术调用与请求参数同名的属性的setter方法来获取请求参数值
      public void setId(Integer id) {
             this.id = id;
      }
      public Integer getId() {return id;}
}

 c) java.util.Date类型的属性可以接收格式为2009-07-20的请求参数值。但如果我们需要接收格式为20091221的请求参数,我们必须定义类型转换器,否则struts2无法自动完成类型转换。

 1 public class UserAction extends ActionSupport {
 2   private Integer id;
 3   private String userName;
 4   private java.util.Date createTime;
 5 
 6   public java.util.Date getCreateTime() {
 7       return createTime;
 8   }
 9   public void setCreateTime(java.util.Date createTime) {
10        this.createTime = createTime;
11   }
12   public String save(){
13       System.out.println("id  "+id);
14       System.out.println("userName   "+userName);
15       System.out.println("createTime   "+createTime);
16       return "save";
17   }
18 }
 
转化失败时,应该转向错误页面
  转向错误页面,应该在struts配置文件中,增加如下代码:
1 <action name="userAction_*" class="cn.itcast.converter.UserAction" method="(1)">
2    <result name="success">/converter/success.jsp</result>
3   <!-- input:当类型转化失败时,要转到input所指向的页面 -->
4   <result name="input">/converter/error.jsp</result>
5 </action>

定制类型转换器说明

    自定义类型转化器必须实现 TypeConverter 接口或对这个接口的某种具体实现做扩展
    
  定制类型转换器说明—底层代码:
  
  定制类型转换器
1 public class DateConverter extends DefaultTypeConverter {
2     
3     public Object convertValue(Map<String, Object> context, Object value, Class toType) {
4                 
5         System.out.println("value = "+value);
6         System.out.println("toType = "+toType);
7         return new Date();
8     }
9 }

* context:

* value:要转换的值,是一个数组,因为struts2底层接

            收值都用request.getParameterValues("createTime")--String[]

* toType:要转换的数据类型

 配置自定义的类型转换器

  在应用程序里使用一个自定义的类型转换器之前, 必须先对它进行配置.
  这种配置既可以 基于字段, 也可以基于类
 
   a) 基于字段配置(局部): 可以为某个动作的各个属性分别制定一个自定义的转换器. 
1. 创建一个属性文件 : ActionClassName-conversion.properties, 该文件需和相对应的动作类(Action)放在同一个目录下, ActionClassName Action 的类名,
   后面的 -conversion.properties是固定写法.在properties文件中的内容为:

                    属性名称=类型转换器的全类名

        对于本例而言,文件的名称应为UserAction- conversion.properties 
     2. 编辑属性文件:

            createTime=cn.itcast.converter.DateConverter

为什么这样配置自定义的类型转换器

  
  
  DateConverter.java
 1 import java.text.ParseException;
 2 import java.text.SimpleDateFormat;
 3 import java.util.Date;
 4 
 5 import sun.misc.JavaAWTAccess;
 6 
 7 import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
 8 
 9 /*
10  * 自定义转换器:
11  *     * 作用:就是把页面中createTime元素的字符串内容转换成java.util.Date
12  */
13 public class DateConverter extends DefaultTypeConverter {
14 
15     @Override
16     public Object convertValue(Object value, Class toType) {
17         
18         //要转换的值:[Ljava.lang.String;@3da850
19         System.out.println("value = "+value);
20         
21         //要转换的类型:class java.util.Date
22         System.out.println("toType = "+toType);
23         
24         if(value==null){
25             return false;
26         }
27         
28         if(toType==null){
29             return false;
30         }
31         
32         if(toType!=java.util.Date.class){
33             return false;
34         }
35         
36         if(value instanceof java.lang.String[]){
37             String [] str = (String[])value;
38             
39             if(str[0]!=null&&str[0].length()>0){
40                 
41                 try {
42                     SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
43                     
44                     return sdf.parse(str[0]);
45                     
46                 } catch (ParseException e) {
47                     /*
48                      *  在struts2框架里,自定义的类型转换器,
49                      *  如果我们不手动抛出异常,struts2框架只捕获异常,但是并不抛出。
50                      *  所以框架就会认为类型转换器转换成功,转向成功页面。
51                      */
52                     throw new RuntimeException(e);
53                     
54                 }
55             }
56         }
57         
58         return new Date();
59     }
60     
61 }

   b) 基于类配置(全局): 

     在 WEB-INF/classes/ 目录下创建 xwork-conversion.properties 文件."

     在properties文件中的内容为:

    待转换的类型=类型转换器的全类名

      对于本例而言, xwork-conversion.properties文件中的内容为:java.util.Date= cn.itcast.converter.DateConverter

 该拦截器负责对错误信息进行拦截器<interceptor name="conversionError "class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>

定制类型转换器—抛出异常
  如果输入一个错误的格式,应该转向错误页面。但实际上为什么还是转向成功页面?
1 try {
2     … …
3 } catch (ParseException e) {
4         e.printStackTrace();...
5          throw new RuntimeException(e);
6 }

   如果转换器中出现异常,该异常必须抛出,不能捕获

    *   只有抛出了异常,struts2拦截器收到异常,才认为转换器出现了异常,才能转到<result name="input">所指向的页面

    *    struts2拦截器没有收到异常,struts2拦截器认为转换成功

定制类型转换器—处理异常1

  • 在 error.jsp 页面中引入
1 <%@ taglib uri="/struts-tags"   prefix="s"%>

  在error.jsp页面中使用<s:fielderror fieldName=“ ”/>打印所有转化的异常错误信息

  •name:指定Action属性的名称

  • 打印某个属性转化的异常错误信息

定制类型转换器—处理异常2

   为什么显示出的错误信息是英文的呢?

   在xwork-core-2.3.3.jar包下com\opensymphony\xwork2的xwork-conversion.properties

   代码:xwork.default.invalid.fieldvalue=Invalid field value for field "{0}".

   如何修改可以让显示出的错误信息是中文的呢?

定制类型转换器—处理异常3

   修改让显示出的错误信息是中文!
  
    • 在与当前 Action 同级目录中,新建 converter.properties (文件名称自定义)资源文件,在该文件中增加如下内容
       xwork.default.invalid.fieldvalue= 无效的字段值 "{0}".
    • 在 struts.xml 文件加载该资源文件
    加载国际化资源文件,如果有多个文件,用","隔开,资源文件的后缀名不用写,加载cn.itcast.converter包下的converter.properties
1 <constant name="struts.custom.i18n.resources" value="cn.itcast.converter.converter"></constant>

     这个配置是针对所有字段给出提示。

定制类型转换器—处理异常4
  针对每个字段给出提示信息!-针对每个字段的提示信息要覆盖针对所有字段的提示信息。
  在converter.properties资源文件中增加如下内容
• 格式: invalid.fieldvalue. xx= 提示信息
    • 内容: invalid.fieldvalue.createTime = 出生时间转化异常

类型转换与复杂对象配合使用
  很多时候, 需要把表单字段映射到多个对象的不同属性上form 标签可以被映射到一个属性的属性.
   
类型转换与Collection配合使用
  Struts 还允许填充 Collection 里的对象, 这常见于需要快速录入批量数据的场合
 
样例代码:
1、jsp
  userform.jsp
 1 <%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
 2 <%@ taglib uri="/struts-tags"   prefix="s"%>
 3 <html>
 4   <head>
 5     <title>My JSP 'index.jsp' starting page</title>
 6     </head>
 7   <body>
 8     <form action="${pageContext.request.contextPath}/converter/userAction_save.action" 
 9           name="form1"  method="post">
10         编号:<input type="text" name="id"><br>
11         姓名:<input type="text" name="userName"><br>
12         出生日期:<input type="text" name="createTime"><br>
13       
14         学历编号:<input type="text" name="edu.eduid"><br>
15         学历名称:<input type="text" name="edu.eduname"><br>
16        
17         员工姓名:<input type="text" name="emps[0].name"><br>
18         员工薪水:<input type="text" name="emps[0].salary"><br>
19       
20         员工姓名:<input type="text" name="emps[1].name"><br>
21         员工薪水:<input type="text" name="emps[1].salary"><br>
22          
23        <input type="submit" value="提交"><br>
24     </form>
25   </body>
26 </html>

   success.jsp

<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/struts-tags"   prefix="s"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
    </head>
  <body>
        成功!!!!<br>
  </body>
</html>

  error.jsp

<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/struts-tags"   prefix="s"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
    </head>
  <body>
        失败!!!! <br>
        <s:fielderror fieldName="createTime"/>
  </body>
</html>
2、java
  UserAction.java
import java.util.Collection;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class UserAction extends ActionSupport {

	/*
	 * 	在struts2框架中,在对应动作类action中,
	 * 	声明与页面中表单元素同名的属性,给出对应的set和get方法。
	 *  struts2框架就会根据反射机制,获取页面中表单元素的值
	 */
	
	//编号:<input type="text" name="id"><br>
	private Integer id;
	
    //姓名:<input type="text" name="userName"><br>
	private String userName;
	
	//出生日期:<input type="text" name="createTime"><br>
	private Date createTime;
	
	/*
	 * 学历编号:<input type="text" name="edu.eduid"><br>
        学历名称:<input type="text" name="edu.eduname"><br>
	 */
	private Edu edu;
	
	/*
	 * 员工姓名:<input type="text" name="name"><br>
        员工薪水:<input type="text" name="salary"><br>
	 */
	Collection<Employee> emps;
	
	public Collection<Employee> getEmps() {
		return emps;
	}

	public void setEmps(Collection<Employee> emps) {
		this.emps = emps;
	}

	public Edu getEdu() {
		return edu;
	}

	public void setEdu(Edu edu) {
		this.edu = edu;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	@Override
	public String execute() throws Exception {
		System.out.println("UserAction ************ execute()");
		return "success";
	}
	
	public String save(){
		System.out.println("UserAction ************ save()");
		
		/*HttpServletRequest request = ServletActionContext.getRequest();
		
		String username = request.getParameter("userName");
		
		System.out.println("username = "+username);*/
		
		System.out.println("id = "+id);
		
		System.out.println("username = "+userName);
		
		System.out.println("createTime = "+createTime);
		
		System.out.println(edu.getEduid()+"  "+edu.getEduname());
		
		return "success";
	}
}

  DateConverter.java

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import sun.misc.JavaAWTAccess;

import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;

/*
 * 自定义转换器:
 * 	* 作用:就是把页面中createTime元素的字符串内容转换成java.util.Date
 */
public class DateConverter extends DefaultTypeConverter {

	@Override
	public Object convertValue(Object value, Class toType) {
		
		//要转换的值:[Ljava.lang.String;@3da850
		System.out.println("value = "+value);
		
		//要转换的类型:class java.util.Date
		System.out.println("toType = "+toType);
		
		if(value==null){
			return false;
		}
		
		if(toType==null){
			return false;
		}
		
		if(toType!=java.util.Date.class){
			return false;
		}
		
		if(value instanceof java.lang.String[]){
			String [] str = (String[])value;
			
			if(str[0]!=null&&str[0].length()>0){
				
				try {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
					
					return sdf.parse(str[0]);
					
				} catch (ParseException e) {
					/*
					 *  在struts2框架里,自定义的类型转换器,
					 *  如果我们不手动抛出异常,struts2框架只捕获异常,但是并不抛出。
					 *  所以框架就会认为类型转换器转换成功,转向成功页面。
					 */
					throw new RuntimeException(e);
					
				}
			}
		}
		
		return new Date();
	}
	
}

  Employee.java

public class Employee {

	/*
	 * 员工姓名:<input type="text" name="name"><br>
        员工薪水:<input type="text" name="salary"><br>
	 */
	private String name;
	
	private Double salary;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Double getSalary() {
		return salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}
	
	
}

  Edu.java

public class Edu {

	//学历编号:<input type="text" name="eduid"><br>
	private Integer eduid;
	
    //学历名称:<input type="text" name="eduname"><br>
	private String eduname;

	public Integer getEduid() {
		return eduid;
	}

	public void setEduid(Integer eduid) {
		this.eduid = eduid;
	}

	public String getEduname() {
		return eduname;
	}

	public void setEduname(String eduname) {
		this.eduname = eduname;
	}
	
}
3、xml
  struts_converter.xml
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE struts PUBLIC
 3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 4     "http://struts.apache.org/dtds/struts-2.3.dtd">
 5 <struts>
 6     <package name="converter" namespace="/converter" extends="struts-default">
 7         <action name="userAction_save" class="cn.itcast.converter.UserAction" method="save">
 8             <result name="success">/converter/success.jsp</result>
 9             <!-- 
10                 * 错误提示:No result defined for action cn.itcast.converter.UserAction and result input 
11                 * 配置如果出错的时候,自动转向到错误页面
12             -->
13             <result name="input">/converter/error.jsp</result>
14         </action>
15     </package>
16 </struts>

   struts.xml

1 <constant name="struts.custom.i18n.resources" 
2         value="cn.zengfansheng.struts.i18n.resources"></constant>
3 <include file="cn/zengfansheng/struts/converter/struts_converter.xml"></include>    

 

4、properties
   UserAction-conversion.properties
1 createTime=cn.zengfansheng.struts.converter.DateConverter

   converter.properties

1 xwork.default.invalid.fieldvalue=\u7C7B\u578B\u8F6C\u6362\u5931\u8D25 "{0}".
2 invalid.fieldvalue.createTime=\u51FA\u751F\u65E5\u671F\u8F6C\u6362\u5931\u8D25

 

   xwork-conversion.properties
1 java.util.Date=cn.zengfansheng.struts.converter.DateConverter

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值