Struts 2(四):类型转换

类型转换是Struts 2的一个很是重要的部分,经过类型转换可以将表单参数转换成Java中的各类类型,本文将详细介绍Struts 2的内建类型转换器和自定义类型转换器。html

第一节 Struts 2内建类型转换器java

1.1 类型转换的意义apache

  Web应用程序的交互是创建在HTTP之上的,互相传递的都是字符串,也就是说服务器接收到的来自用户的数据只能是字符串或者是字符数组,而在Web应用的对象中,每每使用了多种不一样的类型,如整数(int)、浮点数(float)、日期(Date)或者是自定义数据类型等,所以在服务器端必须将字符串转换成合适的数据类型,服务器端完成业务逻辑处理后,又需将其余数据类型转换为String,而后传递给客户端进行显示,具体流程如图所示:数组

 

1.2 内建类型转换器简介服务器

Struts 2为经常使用的数据类型提供了内建的类型转换器,Struts在遇到这些类型时,会自动去调用相应的转换器进行类型转换,Struts 2提供了以下一些内建的类型转换器:app

  A、基本数据类型以及其封装类jsp

  B、日期类型post

  C、集合(Collection)类型测试

  D、集合(Set)类型ui

  E、数组类型

下面几小节内容将对上述内建类型转换器进行简单介绍

 

1.3 基本数据类型转换器

经过基本数据类型转换器可以完成字符串和基础数据类型之间的转换,其中基础数据类型包括boolean、char、byte、short、int、long、float和double八种。

下面经过一个简单的计算器示例来演示如何经过基本数据类型转换器完成字符串和double类型数据之间的转换:

CounterInput.jsp:

<%@page language="java" pageEncoding="gb2312"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>计算器</title>
    </head>
    <body>
<form action="count.action" method="post">
    第一个操做数:<input type="text" name="num1"><br><!--第一个操做数-->
    运算符:<select name="operation">
        <option value="add">+</option><!--加法运算符-->
        <option value="minus">-</option><!--减法运算符-->
        <option value="multiply">*</option><!--乘法运算符-->
        <option value="division">/</option><!--除法运算符-->
    </select><br>
    第二个操做数:<input type="text" name="num2"><br><!--第二个操做数-->
    <input type="submit" value="运算">
    <input type="reset" value="重置">
</form>
    </body>
</html>

CounterOutput.jsp:

<%@page language="java" pageEncoding="gb2312"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>计算结果</title>
    </head>
    <body>
        <s:property value="num1"/>
        <s:property value="operation"/>
        <s:property value="num2"/>=
        <s:property value="sum"/>
    </body>
</html>

CountAction.java:

package com.sanqing.action;

import com.opensymphony.xwork2.ActionSupport;

public class CountAction extends ActionSupport {
    private double num1;            //第一个操做数
    private double num2;            //第二个操做数
    private double sum;                //运算结果
    private String operation;        //运算符
    public double getNum1() {        //得到第一个操做数
        return num1;
    }
    public void setNum1(double num1) {    //设置第一个操做数
        this.num1 = num1;
    }
    public double getNum2() {            //得到第二个操做数
        return num2;
    }
    public void setNum2(double num2) {    //设置第二个操做数
        this.num2 = num2;
    }
    public String getOperation() {        //得到运算符
        return operation;
    }
    public void setOperation(String operation) {//设置运算符
        this.operation = operation;
    }
    public double getSum() {            //得到运算结果
        return sum;
    }
    public void setSum(double sum) {    //设置运算结果
        this.sum = sum;
    }
    public String execute() throws Exception {
        if("add".equals(operation)) {            //若是运算符为加法
            sum = num1 + num2;
        }else if("minus".equals(operation)) {    //若是运算符为减法
            sum = num1 - num2;
        }else if("multiply".equals(operation)) {//若是运算符为乘法
            sum = num1 * num2;
        }else {                                    //若是运算符为除法
            sum = num1 / num2;
        }
        return this.SUCCESS;
    }
}

测试:访问http://localhost:8080/StrutsPro/CounterInput.jsp,其中计算器输入页面以下图所示:

注:在字符串类型和double数据类型之间进行转换时,若是输入一个非数字的数据,如“a”,这时将没法进行类型转换,程序将出现类型转换异常。

 

1.4 基本数据类型的封装类转换器

Struts 2的内置转换器不但能转换基本数据类型,还可以转换基本数据类型的封装类,包括Boolean、Character、Byte、Short、Integer、Long、Float和Double八种。

在下面这段代码中修改上述案例,其运行结果与上例相同:

package com.sanqing.action;

import com.opensymphony.xwork2.ActionSupport;

public class CountAction2 extends ActionSupport {
    private Double num1;            //第一个操做数
    private Double num2;            //第二个操做数
    private Double sum;                //运算结果
    private String operation;        //运算符
    public double getNum1() {        //得到第一个操做数
        return num1;
    }
    public void setNum1(Double num1) {    //设置第一个操做数
        this.num1 = num1;
    }
    public double getNum2() {            //得到第二个操做数
        return num2;
    }
    public void setNum2(Double num2) {    //设置第二个操做数
        this.num2 = num2;
    }
    public String getOperation() {        //得到运算符
        return operation;
    }
    public void setOperation(String operation) {//设置运算符
        this.operation = operation;
    }
    public double getSum() {            //得到运算结果
        return sum;
    }
    public void setSum(Double sum) {    //设置运算结果
        this.sum = sum;
    }
    public String execute() throws Exception {
        if("add".equals(operation)) {            //若是运算符为加法
            sum = num1 + num2;
        }else if("minus".equals(operation)) {    //若是运算符为减法
            sum = num1 - num2;
        }else if("multiply".equals(operation)) {//若是运算符为乘法
            sum = num1 * num2;
        }else {                                    //若是运算符为除法
            sum = num1 / num2;
        }
        return this.SUCCESS;
    }
}

注:在JDK 5.0之后,Java提供了自动封包和解包(也称为自动装箱和拆箱),使得基本数据类型与其封装类之间能够互相自动转换

 

1.5 数组类型转换器

  Struts 2还提供了一个数组类型的转换器,这个转换器很是经常使用,好比多个表单元素的name属性相同,那么提交的参数就再也不是字符串而是一个字符串数组。经过Sturts 2提供的数组类型的转换器就能很方便的将多个相同name属性的表单元素的值封装到Action中的一个数组中。

下面这段代码主要演示Struts 2的数组类型转换器,将多个相同name属性的表单元素的值封装到Action中的一个数组中,须要注意的是表单元素的name必须与Action中的属性名称一致

(1)我的爱好输入页面LikeInput.jsp

<%@page language="java" pageEncoding="gb2312"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>我的爱好</title>
    </head>
    <body>
        <form action="mylike.action" method="post">
            请输入您的我的爱好: <br>
            <input type="checkbox" name="mylike" value="basketball">篮球
            <input type="checkbox" name="mylike" value="football">足球
            <input type="checkbox" name="mylike" value="pingpang">乒乓球
            <input type="checkbox" name="mylike" value="billiards">台球<br>
            <input type="submit" value="提交">
            <input type="reset" value="重置">
        </form>
    </body>
</html>

(2)我的爱好输出页面LikeOutput.jsp

<%@page language="java" pageEncoding="gb2312"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>显示我的爱好</title>
    </head>
    <body>
        你输入的我的爱好包括: <s:property value="mylike"/>
    </body>
</html>

(3)

package com.sanqing.action;

import com.opensymphony.xwork2.ActionSupport;

public class MyLikeAction extends ActionSupport{
    private String[] mylike;                //数组类型用来封装全部的我的爱好
    public String[] getMylike() {            //得到数组
        return mylike;
    }
    public void setMylike(String[] mylike) {//设置数组
        this.mylike = mylike;
    }
    public String execute() throws Exception {
        return this.SUCCESS;                //返回success字符串
    }
    
}

(4)测试

 

1.6 集合类型转换器

  集合类型转换器和数组类型转换器相似,能够经过集合类型来接受参数值。Struts 2提供的集合类型转换器,会将参数值自动添加到集合类型属性中,不一样的是将集合类型转换成字符串类型时,输出了一对中括号

package com.sanqing.action;

import java.util.ArrayList;

import com.opensymphony.xwork2.ActionSupport;

public class MyLikeAction2 extends ActionSupport{
    private ArrayList<String> mylike;                //ArrayList类型用来封装全部的我的爱好
    public ArrayList<String> getMylike() {            //得到mylike属性值
        return mylike;
    }
    public void setMylike(ArrayList<String> mylike) {//设置mylike属性值
        this.mylike = mylike;
    }
    public String execute() throws Exception {
        return this.SUCCESS;                        //返回success字符串
    }
}

 

1.7 日期类型转换器

经过日期类型转换器可以自动完成字符串类型与日期类型之间的转换,不过字符串类型必须符合日期格式规范,不然将出现类型转换错误。

下面这段代码主要演示Struts 2的日期类型转换器,经过输入用户出生日期,提交后自动输出用户年龄

(1)出生日期输入页面DateInput.jsp

<%@page language="java" pageEncoding="gb2312"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>输入出生日期</title>
    </head>
    <body>
        <form action="date.action" method="post">
            请输入您的出生日期: <br>
            <input type="text" name="mybirth">
            <input type="submit" value="提交">
            <input type="reset" value="重置">
        </form>
    </body>
</html>

(2)出生日期输出页面DateOutput.jsp

<%@page language="java" pageEncoding="gb2312"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>当前年龄</title>
    </head>
    <body>
        经计算,年龄为<s:property value="age"/>
    </body>
</html>

(3)Action

package com.sanqing.action;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class DateAction extends ActionSupport{
    private Date mybirth;                                //出生日期
    private Long age;                                    //年龄    
    public Date getMybirth() {                            //得到出生日期
        return mybirth;
    }
    public void setMybirth(Date mybirth) {                //设置出生日期
        this.mybirth = mybirth;
    }
    public Long getAge() {                                //得到年龄信息
        return age;
    }
    public void setAge(Long age) {                        //设置年龄信息
        this.age = age;
    }
    public String execute() throws Exception {
        Date now = new Date();                            //得到当前日期
        long nowTime = now.getTime();                    //得到当前日期毫秒数
        long birthTime = mybirth.getTime();                //得到生日的毫秒数
        long difference = nowTime - birthTime;            //得到毫秒差
        long differenceDay = difference/(1000*60*60*24);//计算出总天数
        age = differenceDay/365+1;                        //计算出年数差加一
        return this.SUCCESS;                            //返回success字符串
    }
}

注:在测试上述代码时,输入出生日期时必须严格按照日期格式进行输入,日期格式为yyyy-MM-dd,其中yyyy为年份,如1998;MM为月份,如12;dd为该月的某一天,如03。

 

第二节 自定义类型转换器

  Struts 2已经实现了一些经常使用的类型转换,可是毕竟这些类型转换器仍是有限的,若是是开发者本身定义的数据类型,就必须自定义类型转换器来进行转换,Struts 2的类型转换器是基于OGNL实现的,在lib目录下的ognl-2.6.11.jar中能够找到TypeConverter类,此处略去其详细内容。

  下面来看如何建立自定义的类型转换器,假如如今有一个自定义的类Point类,包括x和y两个属性,分别表明x坐标值和y坐标值。那么若是经过表单的参数值来设置Point类的属性呢,这时就必须经过自定义类型转换器来完成。

 2.1 实现自定义类型转换器

package com.sanqing.converter;

import java.util.Map;

import ognl.DefaultTypeConverter;

import com.sanqing.bean.Point;

public class PointConverter extends DefaultTypeConverter {
    public Object convertValue(Map context, Object value, Class toType) {
        if(Point.class == toType) {//首先判断若是要转换的类型是否为Point
            String[] paramStrs = (String[])value;//将请求参数值转换成String数组
            String[] pointArray = paramStrs[0].split(",");//经过逗号分隔字符串
            Point point = new Point();//新建一个Point实例
            point.setX(Integer.parseInt(pointArray[0]));//设置x坐标
            point.setY(Integer.parseInt(pointArray[1]));//设置y坐标
            return point;//返回转换后的Point实例
        }
        if(String.class == toType) {//若是要转换的类型为String
            Point point = (Point)value;//经过强制转换把value转换成Point实例
            int x = point.getX();//得到x坐标
            int y = point.getY();//得到y坐标
            StringBuilder sb = new StringBuilder();//实例化一个StringBuilder用来构造字符串
            sb.append("x坐标为").append(x).append(",y坐标为").append("y");//构造字符串
            return sb.toString();//返回StringBuilder的字符串形式
        }
        return null;
    }
}

 

2.2 使用Struts 2提供的StrutsTypeConverter

package com.sanqing.converter;

import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;

import com.sanqing.bean.Point;

public class PointConverter2  extends StrutsTypeConverter{
    //从字符串类型转换成自定义数据类型
    public Object convertFromString(Map context, String[] values, Class toClass) {
        String[] pointArray = values[0].split(",");//经过逗号分隔字符串
        Point point = new Point();//新建一个Point实例
        point.setX(Integer.parseInt(pointArray[0]));//设置x坐标
        point.setY(Integer.parseInt(pointArray[1]));//设置y坐标
        return point;//返回转换后的Point实例
    }
    //从自定义数据类型转换成字符串类型
    public String convertToString(Map context, Object o) {
        Point point = (Point)o;//经过强制转换把o转换成Point实例
        int x = point.getX();//得到x坐标
        int y = point.getY();//得到y坐标
        StringBuilder sb = new StringBuilder();//实例化一个StringBuilder用来构造字符串
        sb.append("x坐标为").append(x).append(",y坐标为").append("y");//构造字符串
        return sb.toString();//返回StringBuilder的字符串形式
    }

}

 

2.3 注册局部类型转换器

(1)PointInput.jsp

<%@page language="java" pageEncoding="gb2312"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>输入坐标</title>
    </head>
    <body>
        <form action="point.action" method="post">
            请输入点坐标(如:12,13): <br>
            <s:fielderror name="point"/>
            <input type="text" name="point"><br>
            <input type="submit" value="提交">
            <input type="reset" value="重置">
        </form>
    </body>
</html>

 

(2)PointOutput.jsp

<%@page language="java" pageEncoding="gb2312"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>输出坐标</title>
    </head>
    <body>
        <s:property value="point"/>
    </body>
</html>

 

(3)

package com.sanqing.action;

import com.opensymphony.xwork2.ActionSupport;
import com.sanqing.bean.Point;

public class PointAction extends ActionSupport {
    private Point point;                //point属性
    public Point getPoint() {            //得到point属性值
        return point;
    }
    public void setPoint(Point point) {    //设置point属性值
        this.point = point;
    }
    public String execute() throws Exception {
        return SUCCESS;
    }
}

 

2.4 注册全局类型转换器

2.5 类型转换执行流程

2.6 类型转换中错误处理

2.7 输出指定的错误信息

若是类型转换出错,Struts 2将自动调用ConversionError拦截器将错误提示信息保存到FieldError中

相关文章
相关标签/搜索