Struts2类型转换

概述

  • 从一个 HTML 表单到一个 Action 对象, 类型转换是从字符串到非字符串.
    • HTTP 没有 “类型” 的概念. 每一项表单输入只可能是一个字符串或一个字符串数组. 在服务器端, 必须把 String 转换为特定的数据类型
  • 在 struts2 中, 把请求参数映射到 action 属性的工作由 Parameters 拦截器负责, 它是默认的 defaultStack 拦截器中的一员. Parameters 拦截器可以自动完成字符串和基本数据类型之间转换.

接收请求参数

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

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

1.UserAction文件
package cn.itcast.converter;

import com.opensymphony.xwork2.ActionSupport;

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;




    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);



        return "success";
    }

}
2.配置struts_converter.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <package name="converter" namespace="/converter" extends="struts-default">
        <action name="userAction_save" class="cn.itcast.converter.UserAction" method="save">
            <result name="success">/converter/success.jsp</result>
            <!-- 
                * 错误提示:No result defined for action cn.itcast.converter.UserAction and result input 
                * 配置如果出错的时候,自动转向到错误页面
            -->
            <result name="input">/converter/error.jsp</result>
        </action>

    </package>

</struts>

这里写图片描述

3.配置struts.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <include file="cn/itcast/converter/struts_converter.xml"></include>
</struts>
4.jsp页面:

userform.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>
    <form action="${pageContext.request.contextPath}/converter/userAction_save.action" 
          name="form1"  method="post">
        编号:<input type="text" name="id"><br>
        姓名:<input type="text" name="userName"><br>
   出生日期:<input type="text" name="createTime"><br>



        学历编号:<input type="text" name="edu.eduid"><br>
        学历名称:<input type="text" name="edu.eduname"><br>



        员工姓名:<input type="text" name="emps[0].name"><br>
        员工薪水:<input type="text" name="emps[0].salary"><br>


        员工姓名:<input type="text" name="emps[1].name"><br>
        员工薪水:<input type="text" name="emps[1].salary"><br>

       <input type="submit" value="提交"><br>
    </form>
  </body>
</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>

  </body>
</html>
5.测试结果

这里写图片描述
显示结果:
这里写图片描述
后台输出:
这里写图片描述


定制类型转换器

接受日期类型参数

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

  • 自定义类型转化器必须实现 ongl.TypeConverter 接口或对这个接口的某种具体实现做扩展
    这里写图片描述
1.DateConverter文件
package cn.itcast.converter;

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

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

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

    @Override
    public Object convertValue(Object value, Class toType) {

        //要转换的值:value = [Ljava.lang.String;@6b125fac
        System.out.println("value = "+value);//value = [Ljava.lang.String;@6b125fac

        //要转换的类型:class java.util.Date
        System.out.println("toType = "+toType);//toType = class java.util.Date

        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();
    }
}

配置自定义的类型转换器

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

2.基于字段配置自定义的类型转换器UserAction-conversion.properties

这里写图片描述

createTime=cn.itcast.converter.DateConverter
3.测试

这里写图片描述
页面显示:
这里写图片描述
后台输出:
这里写图片描述
修改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>

测试错误格式:
这里写图片描述
结果:
这里写图片描述

配置修改错误提示信息为中文
        * 在动作类action同目录下,创建一个名为"converter.properties"的资源文件

        * 该资源文件配置如下:

            * 针对所有字段:
                xwork.default.invalid.fieldvalue=类型转换失败 "{0}".

            * 针对某个字段:
                invalid.fieldvalue.createTime=出生日期转换失败

        * 在struts.xml文件进行配置:
            <constant name="struts.custom.i18n.resources" 
                    value="cn.itcast.converter.converter">
            </constant>   

这里写图片描述
测试:
这里写图片描述

基于类配置自定义的类型转换器

基于类配置(全局):
在 WEB-INF/classes/ 目录下创建 xwork-conversion.properties 文件.
在properties文件中的内容为:
待转换的类型=类型转换器的全类名
对于本例而言, xwork-conversion.properties文件中的内容为:
java.util.Date= cn.itcast.converter.DateConverter
这里写图片描述
测试:
这里写图片描述


类型转换总结:

类型转换:

* 从页面中获取对应的内容

    * 在动作类action中,声明与页面中表单name属性的值同名的属性
    * 提供get和set方法
    * struts2框架就会通过反射机制,从页面中获取对应的内容

* struts2框架不能把页面中获取到的字符串类型转换成任何类型

* 当struts2框架不能把页面中获取到的字符串类型进行转换时,就需要自定义类型转换器

* 自定义类型转换器:

    * 要么实现TypeConverter接口或者继承TypeConverter接口的某个实现类,我们继承DefaultTypeConverter类

    * 重写convertValue(Object value, Class toType){}方法

        * 参数"value":要转换的值
        * 参数"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);

                }
            }
        }

    * 两种注册方式:
        * 基于字段的(局部)

            * 在动作类action同目录下,创建一个名为"UserAction-conversion.properties"的资源文件
                * UserAction为动作类action的名称
                * "-conversion.properties"是固定写法

            * 其内容配置如下:
                createTime=cn.itcast.converter.DateConverter

        * 基于类的(全局)

            * 在src目录下,创建一个名为"xwork-conversion.properties"的资源文件
                * 该资源文件的名称是固定的

            * 其内容配置如下:
                java.util.Date=cn.itcast.converter.DateConverter

    * 如果在页面中输入一个不正确的值的时候,不手动抛出异常,页面依然转向成功页面
        /*
         *  在struts2框架里,自定义的类型转换器,
         *  如果我们不手动抛出异常,struts2框架只捕获异常,但是并不抛出。
         *  所以框架就会认为类型转换器转换成功,转向成功页面。
         */

    * 配置修改错误提示信息为中文

        * 在动作类action同目录下,创建一个名为"converter.properties"的资源文件

        * 该资源文件配置如下:

            * 针对所有字段:
                xwork.default.invalid.fieldvalue=类型转换失败 "{0}".

            * 针对某个字段:
                invalid.fieldvalue.createTime=出生日期转换失败

        * 在struts.xml文件进行配置:
            <constant name="struts.custom.i18n.resources" 
                    value="cn.itcast.converter.converter">
            </constant>

类型转换与复杂对象配合使用

很多时候, 需要把表单字段映射到多个对象的不同属性上
form 标签可以被映射到一个属性的属性.
这里写图片描述
userform.jsp页面:
这里写图片描述

1.修改UserAction
package cn.itcast.converter;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

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;


    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);//createTime = Sun Nov 20 00:00:00 CST 2016

        System.out.println(edu.getEduid()+"  "+edu.getEduname());
        return "success";
    }

}
2.添加Edu类
package cn.itcast.converter;

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.测试

这里写图片描述
页面显示:
这里写图片描述
后台输出:
这里写图片描述


类型转换与Collection配合使用

Struts 还允许填充 Collection 里的对象, 这常见于需要快速录入批量数据的场合
这里写图片描述
userform.jsp
这里写图片描述

1.修改UserAction
package cn.itcast.converter;

import java.util.Collection;
import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

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);//createTime = Sun Nov 20 00:00:00 CST 2016

        System.out.println(edu.getEduid()+"  "+edu.getEduname());

        System.out.println("emps.size() ===" + emps.size());
        return "success";
    }

}
2.增加Employee类
package cn.itcast.converter;

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;
    }


}
3.测试

这里写图片描述
页面显示:
这里写图片描述
后台输出:
这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值