2_Struts2的类型转换

struts2对于java内置的类型有非常好的处理,比如int,date可以自动转换。
对于用户自定义的类型需要自定义转换
1 采用ognl的转换类进行局部的转换
input.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>struts2类型转换</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">

</head>

<body>

<h3>使用逗号将点的两个坐标分隔开</h3>
<!-- 实际的流程是先转化,然后再验证,如果转化不成功则无需验证 -->
<s:form action="pointConverter">
<!-- 对应一个类 -->
<s:textfield name="point" label="point"></s:textfield>
<!-- 对应一个整数 -->
<s:textfield name="age" label="age"></s:textfield>
<!-- 对应一个字符串 -->
<s:textfield name="username" label="username"></s:textfield>
<!-- 对应一个日期 -->
<s:textfield name="date" label="birthday"></s:textfield>

<s:submit label="submit"></s:submit>

</s:form>
</body>
</html>




//自定义的bean
package com.test.bean;

public class Point {
private int x;
private int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}

}
//用户自定义的转换类
package com.test.converter;

import java.util.Map;

import ognl.DefaultTypeConverter;

import com.test.bean.Point;

public class PointConverter extends DefaultTypeConverter
{

@Override
//context表示应用的上下文,value入参,toType表示转换成的类型
public Object convertValue(Map context, Object value, Class toType)
{
//String到自定义类型的转换
if(Point.class == toType)
{
Point point = new Point();

String[] str = (String[])value;

String[] paramValues = str[0].split(",");

int x = Integer.parseInt(paramValues[0]);
int y = Integer.parseInt(paramValues[1]);

point.setX(x);
point.setY(y);

return point;
}
//自定义类型到String的转换
if(String.class == toType)
{
Point point = (Point)value;

int x = point.getX();
int y = point.getY();

String result = "[x=" + x + " , y=" + y + "]";

return result;
}

return null;
}

}


//业务处理的Action
package com.test.action;

import java.util.Date;

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

public class PointAction extends ActionSupport{
private Point point;
private int age;
private String username;
private Date date;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String execute() throws Exception {
return this.SUCCESS;
}

}



output.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>My JSP 'output.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->

</head>

<body>
<!-- 该标签表示再action中定义的属性,将自动调用属性的get方法显示,实际对应的是方法 -->
point:<s:property value="point"/><br/>
age:<s:property value="age"/><br/>
username:<s:property value="username"/><br/>
date:<s:property value="date"/>

</body>
</html>


struts.xml

<action name="pointConverter" class="com.test.action.PointAction">
<result name="input">/input.jsp</result>
<result name="success">/output.jsp</result>
</action>

一切都完成了,需要转换了
要在Action下建立PointAction-conversion.properties文件,文件名称是[ActionName]-conversion.properties
内容是point=com.test.converter.PointConverter
表示action中的需要转换的属性及对应的转换类,如果多个属性需要转换可以一并加入
如果我们需要转换多点坐标,可以在action中添加多个属性以及对应的-conversion.properties中分别对这三个属性进行转换的配置
当然 这样做可以实现我们的需求,可是看起来好像有没有什么必要,尤其是一旦有所变化维护起来就会增加业务量,所以我们在下面引入了全局类型转化。

2 采用全局类型转换
全局类型转换也需要一个配置文件[color=red]xwork-conversion.properties[/color]名称固定,与struts.xml在同一目录下,既class目录下。
全局类型转换的配置文件内容与局部类型转换类似,但略有不同
局部类型转换

point=com.test.converter.PointConverter
point2=com.test.converter.PointConverter

等号左边表示的是需要转换的action中的属性名,等号右边表示的是要用的转换类

全局类型转换
com.test.bean.Point=com.test.converter.PointConverter

等号左边表示的是需要转换的具体类全称,以后碰到此类都自动转换,等号右边表示要用到的转换类
这样就大大的减轻了我们的工作量和维护成本。
input.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>struts2类型转换</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">

</head>

<body>

<h3>使用逗号将点的两个坐标分隔开</h3>
<!-- 实际的流程是先转化,然后再验证,如果转化不成功则无需验证 -->
<s:form action="pointConverter">
<!-- 对应一个类 -->
<s:textfield name="point" label="point"></s:textfield>
<s:textfield name="point2" label="point"></s:textfield>
<s:textfield name="point3" label="point"></s:textfield>
<!-- 对应一个整数 -->
<s:textfield name="age" label="age"></s:textfield>
<!-- 对应一个字符串 -->
<s:textfield name="username" label="username"></s:textfield>
<!-- 对应一个日期 -->
<s:textfield name="date" label="birthday"></s:textfield>

<s:submit label="submit"></s:submit>

</s:form>
</body>
</html>


output.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>My JSP 'output.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->

</head>

<body>
<!-- 该标签表示再action中定义的属性,将自动调用属性的get方法显示,实际对应的是方法 -->
point:<s:property value="point"/><br/>
point2:<s:property value="point2"/><br/>
point3:<s:property value="point3"/><br/>
age:<s:property value="age"/><br/>
username:<s:property value="username"/><br/>
date:<s:property value="date"/>

</body>
</html>


PointAction.java

package com.test.action;

import java.util.Date;

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

public class PointAction extends ActionSupport{
private Point point;
private Point point2;
private Point point3;
private int age;
private String username;
private Date date;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String execute() throws Exception {
return this.SUCCESS;
}
public Point getPoint2() {
return point2;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public Point getPoint3() {
return point3;
}
public void setPoint3(Point point3) {
this.point3 = point3;
}

}



3 使用struts提供的转换类StrutsTypeConverter来实现转换
struts2为了简化我们的转换类,他给我们提供了一个封装好的转换类,
当然底层的转化类还是ognl。下面我们将上面PointConverter的转换类重写一下,并实现同样的功能

package com.test.converter;

import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;

import com.test.bean.Point;

public class PointConverter2 extends StrutsTypeConverter {

@Override
//从字符串转换到对象
public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
Point point = new Point();
String[] paramValues = arg1[0].split(",");

int x = Integer.parseInt(paramValues[0]);
int y = Integer.parseInt(paramValues[1]);

point.setX(x);
point.setY(y);
return point;
}

@Override
//从对象转换到字符串
public String convertToString(Map arg0, Object arg1) {
Point point = (Point)arg1;

int x = point.getX();
int y = point.getY();
String result = "[ x = "+ x +" , y = "+ y +" ]";
return result;
}

}


我们可以将xwork-conversion.properties中的com.test.bean.Point=com.test.converter.PointConverter换成com.test.bean.Point=com.test.converter.PointConverter2 进行测试

4 对集合类型进行转换
PointConverter3

public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
List<Point> list = new ArrayList<Point>();
for(String value:arg1)
{
Point point = new Point();

String [] paramValues = value.split(",");

int x = Integer.parseInt(paramValues[0]);
int y = Integer.parseInt(paramValues[1]);

point.setX(x);
point.setY(y);

list.add(point);
}
return list;
}

@Override
public String convertToString(Map arg0, Object arg1) {
List<Point> list = (List<Point>)arg1;

StringBuilder sb = new StringBuilder();

int number = 0;

sb.append("[");
for(Point point : list){
++number;
int x = point.getX();
int y = point.getY();

sb.append(number).append(" x = ").append(x).append(", y = ").append(y).append(" ");
}

sb.append(" ]");
return sb.toString();
}

input.jsp

<s:textfield name="point" label="point"></s:textfield>
<s:textfield name="point" label="point2"></s:textfield>
<s:textfield name="point" label="point3"></s:textfield>

PointAction

private List<Point> point;

建议属性文件使用局部的
point=com.test.converter.PointConverter3
5 采用对象属性方式的类型转换
该方式无需属性文件,无需转化类
struts2会直接赋值到对象的属性上
input.jsp

<s:textfield name="point.x" label="x"></s:textfield>
<s:textfield name="point.y" label="y"></s:textfield>

output.jsp

x:<s:property value="point.x"/><br/>
y:<s:property value="point.y"/><br/>

PointAction.java

private Point point;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}

[color=red]注意[/color]:Point必须包含一个无参数的构造方法

6 类型转换的校验错误处理
当服务器不能对用户输入的类型进行成功转换的时候(遇到类型转换错误的时候,比如我们将age输入abc),struts2框架自动生成一条错误信息,并且将该错误信息放到addFieldError里面,返回到出错页面并提示用户Invalid 。。。。但是对于用户来说并不友好。
我们需要将他改成我们希望的错误信息。
我们需要在struts.xml中加入

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<!-- 表示常量 -->
<constant name="struts.custom.i18n.resources" value="message"></constant>
<package name="struts2" extends="struts-default">
<!-- name对应表单的action,class对应于处理类 -->
<action name="login" class="com.test.action.LoginAction">
<!-- result标签默认匹配success,这里可以省略name="success" -->
<result name="success">/result.jsp</result>
<!-- 未通过validate方法的时候跳转到此 -->
<result name="input">/login2.jsp</result>
<result name="failer">/login2.jsp</result>
</action>
<action name="pointConverter" class="com.test.action.PointAction">
<result name="input">/input.jsp</result>
<result name="success">/output.jsp</result>
</action>
</package>

</struts>

建立名为message.properties的资源文件

xwork.default.invalid.fieldvalue={0} error

这样 以后的类型转换的错误信息就变成 .. error
比如 age error
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值