Struts2学习(九)类型转换器
类型转换器的背景和意义
类型转换是日常web开发中不可避免的一部分
因为从表单提交到后台的数据都是以String为数据默认类型,而我们后台封装成对象时则可能有多种类型形式。
按照以往方式来进行数据类型的转换是通过java的类型转换来实现的,具体的步骤为:
Int age = Integer.valueOf(request.getParameter("age"));
Double money = Double .valueOf(request.getParameter("money"))
Struts2数据类型转换
在Struts2当中,为我们提供了基本数据类型之间的自动转换和封装,而String与基本数据类型之间的转换是由Struts2框架自动完成的:
- String和boolean完成字符串与布尔值之间的转换
- String和char完成字符串与字符之间的转换
- String和int、Integer完成字符串与整型之间的转换
- String和Long完成字符串与长整型值之间的转换
- String和Double完成字符串与双精度浮点值的转换
- String和Float完成字符串和单精度浮点之间的转换
- String和数组在默认的情况,数组元素是字符串,如果用户定义类型转换器,也可以是其它复合数据类型
- String和Date完成字符串和日期类型之间的转换(格式必须xxxx-xx-xx)
但一些自定义的数据类型的转换就要用到Struts2为我们所提供的方法。
struts2为我们提供了两种不同的类型转换器:局部类型转换器和全局类型转换器。
局部类型转换器
所谓局部类型转换器就是:只作用于一个action类!
示例演示
我们来编写一个Date类型的类型转换器,表单输入的格式为:20120101
在进行类型转换器的编写之前首先编写对应的JSP界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="ch08TestAction1.action">
请输入日期(示例:20120101):<input type="text" name="position">
<input type="submit" value="提交">
</form>
</body>
</html>
第一步:创建自定义类型转换器类,继承DefaultTypeConverter 类,重写其中的convertValue方法
package cn.lovepi.chapter08.action;
import ognl.DefaultTypeConverter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
/**
* Date类型转换器-局部类型转换器(只能作用于一个action类)
* ---------------------------------
* 我们实现类型转换器有两种方法:
* 1.继承ognl的DefaultTypeConverter类或者实现TypeConverter接口。
* 2.基于Struts2库,实际上struts2库也是基于ognl的二次封装
* 只是简化了一定的操作,也是继承DefaultTypeConverter类,只是包名不同而已
*
* 两种方式的区别:
* ognl只重写一个方法,实现双向的转换
* struts2则重写两个方法,
* 一个是从字符串转换为某种类型,convertFromString
* 另一个是从某种类型转换为字符串,convertToString
* ----------------------------------------------------
* 最后还需将转换类和action类关联在一起,即在action类同包下创建关联文件。
*/
public class DateConver extends DefaultTypeConverter{
/**
* 类型转换方法
* 此方法根据toType来判断是否执行
* @param context 类型转换的上下文
* @param value 前台传递过来的数据
* @param toType 转换后的目标类型
* @return
*/
@Override
public Object convertValue(Map context, Object value, Class toType) {
//struts2基于更全面的考虑,将参数以数组的方式接收
// 防止用户提交的要转换的数据是多选
String[] params= (String[]) value;
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
Date da=null;
try {
da=sdf.parse(params[0]);
} catch (ParseException e) {
e.printStackTrace();
}
return da;
}
}
第二步:创建局部转换器配置文件
名字格式:ActionName-conversion.properties
文件位置:action类同包下
内容:属性名=自定义转换器路径
例(times =com.jike.coverter.DateTypeConverter)
首先编写需要用到的Action:TestAction
package cn.lovepi.chapter08.action;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
/**
* 类型转换器-测试Action
* 首先没有使用转换器的时候讲解错误
* 基本数据类型可以被struts2自动转换,如int的属性,表单数据可直接转为uint
* 但Date类型不是基本数据类型,得自己手动的写一个转换的方法
*/
public class TestAction extends ActionSupport{
private Date times;
@Override
public String execute() throws Exception {
System.out.println("时间:"+times.toString());
return SUCCESS;
}
public Date getTimes() {
return times;
}
public void setTimes(Date times) {
this.times = times;
}
}
将其配置在struts.xml中
<package name="chapter08" extends="struts-default">
<action name="ch08TestAction" class="cn.lovepi.chapter08.action.TestAction">
<result name="success">/chapter08/index.jsp</result>
</action>
</package>
编写配置文件:TestAction-conversion.properties
times=cn.lovepi.chapter08.conver.DateConver
其中:左边的是属性的名称,右边的是转换器的全路径名
全局类型转换器
所谓局部类型转换器就是:作用于所有的action类!
示例演示 :坐标类型转换
我们来编写一个坐标的类型转换器,表单输入的格式为:12.8,13.6
在进行类型转换器的编写之前首先编写对应的JSP界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="ch08TestAction1.action">
请输入坐标值(示例:12.8,13.6):<input type="text" name="position">
<input type="submit" value="提交">
</form>
</body>
</html>
对应转换结果展示界面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<s:property value="position"/>
</body>
</html>
以及演示所用到的bean对象:
package cn.lovepi.chapter08.bean;
/**
* 坐标实体类
*/
public class MyPosition {
private float x;
private float y;
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
}
第一步:创建自定义类型转换器类,继承DefaultTypeConverter 类,重写其中的convertValue方法
package cn.lovepi.chapter08.conver;
import cn.lovepi.chapter08.bean.MyPosition;
import ognl.DefaultTypeConverter;
import java.util.Map;
/**
* 全局转换器
*/
public class PositionConver extends DefaultTypeConverter{
@Override
public Object convertValue(Map context, Object value, Class toType) {
MyPosition position;
//假如是从前台传到后台
if (toType== MyPosition.class){
String[] params= (String[]) value;
String[] xy=params[0].split(",");
position=new MyPosition();
position.setX(Float.valueOf(xy[0]));
position.setY(Float.valueOf(xy[1]));
return position;
}
//从后台传到前台,在界面上使用<s:property来显示
if (toType==String.class){
position= (MyPosition) value;
return "坐标:("+position.getX()+","+position.getY()+")";
}
return null;
}
}
第二步:创建全局转换器配置文件
名字格式:xwork-conversion.properties
文件位置:项目根目录,src下
内容:类型名=自定义转换器路径
例(java.util.Date =com.jike.coverter.DateTypeConverter)
首先创建对应的Action,TestAction1
package cn.lovepi.chapter08.action;
import cn.lovepi.chapter08.bean.MyPosition;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
/**
* 全局转换器Action
*/
public class TestAction1 extends ActionSupport{
MyPosition position;
@Override
public String execute() throws Exception {
System.out.println("X坐标:"+position.getX()+",Y坐标:"+position.getY());
ServletActionContext.getRequest().setAttribute("position",position);
return SUCCESS;
}
public MyPosition getPosition() {
return position;
}
public void setPosition(MyPosition position) {
this.position = position;
}
}
将其配置在struts.xml中
<package name="chapter08" extends="struts-default">
<action name="ch08TestAction1" class="cn.lovepi.chapter08.action.TestAction1">
<result name="success">/chapter08/po.jsp</result>
</action>
</package>
接下来在src目录下创建全局转换器配置文件xwork-conversion.properties
cn.lovepi.chapter08.bean.MyPosition=cn.lovepi.chapter08.conver.PositionConver
其中:左边的是要转换的类型的全路径名,右边的是所需要的转换器的全路径名