• 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)放在同一个目录下,ActionClassNameAction的类名,
       后面的-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\xwork2xwork-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
  • 相关阅读:
    Hausdorff distance between mesh and its symmertic one.
    Fast algorithm to compute minimum volume oriented bounding box
    C++文件读写详解(ofstream,ifstream,fstream)
    libCURL开源库在VS2010环境下编译安装,配置详解
    VPB和OSGGIS安装
    OpenSceneGraph 笔记--如何导出三角形数据
    OpenGL编程指南(第七版)
    osgAnimation例子的注释的注释
    osg 示例程序解析之osgdelaunay
    VS2010+64+OSG3.2.1之五Plugins dae编译
  • 原文地址:https://www.cnblogs.com/hacket/p/3082437.html
Copyright © 2020-2023  润新知