[Struts2学习笔记] -- 自定义类型转换
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.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>
<h3>输入坐标值,格式为x,y,x和y的类型是int类型</h3>
<s:form method="post" action="point" namespace="/">
<!-- 输入坐标值,格式为x,y,x和y的类型是int类型 -->
<s:textfield label="point" name="point"></s:textfield>
<s:submit value="submit"></s:submit>
</s:form>
</body>
</html>
index.jsp代码
Struts2的自定义类型转换可以通过重写继承DefaultTypeConverter类来完成,也可以通过Struts2提供的模版重写方法来完成。并且有局部类型转换和全局类型转换两种,首先来看一下通过继承DefaultTypeConverter类来实现类型转换的方法。建立一个页面,其中有一个文本框,需要输入坐标值,用','来分割x和y,如图:
代码如下:
index.jsp代码
接着,编写一个Point类,有x和y两个字段,用int表示,代码如下:
package cn.net.bysoft.lesson3; public class Point {
public Point() {
} public Point(int x, int y) {
super();
this.x = x;
this.y = 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;
} private int x;
private int y;
}
Point类
然后开始编写继承DefaultTypeConverter类的转换类,这里命名为PointConverter.java,代码如下:
package cn.net.bysoft.lesson3; import java.util.Map; import ognl.DefaultTypeConverter; public class PointConverter extends DefaultTypeConverter { @Override
public Object convertValue(Map context, Object value, Class toType) {
if (Point.class == toType) {
// 用实体的类型与toType比较,等于客户端传递到服务端数据。
Point point = new Point();
// 客户端传递过来的数据为String数组,因为控件的(比如input空间)name可以有多个。
// 此处其实和HttpServletRequest.getParameterValues(String name)方法效果相同。
String[] strArray = (String[]) value;
// 解析字符串。
String[] paramValues = strArray[0].split(",");
int x = Integer.parseInt(paramValues[0]);
int y = Integer.parseInt(paramValues[1]);
point.setX(x);
point.setY(y); return point;
} if (String.class == toType) {
// 用String类型与toType比较,等于服务器发送到客户端数据。
Point point = (Point) value;
int x = point.getX();
int y = point.getY();
StringBuffer sb = new StringBuffer();
sb.append("[x = ");
sb.append(x);
sb.append(", y = ");
sb.append(y);
sb.append("]"); return sb.toString();
} return null;
} }
PointConverter
其中重写convertValue方法进行类型转换,这个方法参数,toType类型若等于"某某类名".class则代表要将Object value转换成Java实体类,也就是客户端传递到服务端的数据需要进行类型转换。假如toType类型等于String.class则等于服务器像客户端发送数据,需要将对象转换成字符串。具体的转换方法可根据实际情况编写。
接下来可以创建一个Action用于控制服务端与客户端的请求了,代码与配置如下:
package cn.net.bysoft.lesson3; import com.opensymphony.xwork2.ActionSupport; public class PointAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = -2035413550978816228L; @Override
public String execute() throws Exception {
return SUCCESS;
} public Point getPoint() {
return point;
} public void setPoint(Point point) {
this.point = point;
} private Point point;
}
PointAction代码
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="struts2_3_24_1" extends="struts-default">
<action name="helloWorld" class="cn.net.bysoft.lesson1.HelloWorldAction">
<result>lesson1/hello.jsp</result>
</action>
<action name="login" class="cn.net.bysoft.lesson2.LoginAction">
<result name="success">/lesson2/success.jsp</result>
<result name="input">/lesson2/login.jsp</result>
</action>
<action name="point" class="cn.net.bysoft.lesson3.PointAction">
<result name="success">/lesson3/output.jsp</result>
<result name="input">/lesson3/index.jsp</result>
</action>
</package>
</struts>
PointAction的struts.xml配置
最后,最关键的是要编写一个配置文件来声明转换的信息,使用局部转换需要在Action的包下建立一个同名的加-conversion.properties属性文件,如PointAction-conversion.properties。内容如下:
point=cn.net.bysoft.lesson3.PointConverter
等号左侧是Action中的字段名称,右侧是使用我们的PointConverter类进行转换。以上工作完成后,可以进行类型转换,编写一个输出页面测试类型转换,代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <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>
point:<s:property value="point"/>
</body>
</html>
output.jsp代码
有一点需要注意的是,在PointConverter.java类中,在客户端向服务端请求类型转换时,参数Object value是一个字符串数组(String[]),因为页面中控件的name属性可以有多个,一次向服务端发送多个Point对象存放到数组中,请看如下代码:
<h3>输入坐标值,格式为x,y,x和y的类型是int类型</h3>
<s:form method="post" action="point" namespace="/">
<!-- 输入坐标值,格式为x,y,x和y的类型是int类型 -->
<s:textfield label="point" name="point"></s:textfield>
<s:textfield label="point" name="point"></s:textfield>
<s:textfield label="point" name="point"></s:textfield>
<s:submit value="submit"></s:submit>
</s:form>
所以,在处理类型转换时,可以一次进行多个对象的类型转换,新创建一个局部类型转换类,实现转换客户端传递过来多个Point并放到集合中,代码如下:
package cn.net.bysoft.lesson3; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import ognl.DefaultTypeConverter; public class PointConverter2 extends DefaultTypeConverter { @Override
public Object convertValue(Map context, Object value, Class toType) {
if (List.class == toType) {
// 用实体的类型与toType比较,等于客户端传递到服务端数据。
List<Point> points = new ArrayList<Point>();
// 客户端传递过来的数据为String数组,因为控件的(比如input空间)name可以有多个。
String[] strArray = (String[]) value;
for (String str : strArray) {
// 解析字符串。
String[] paramValues = str.split(",");
int x = Integer.parseInt(paramValues[0]);
int y = Integer.parseInt(paramValues[1]);
Point point = new Point();
point.setX(x);
point.setY(y);
points.add(point);
}
return points;
} if (String.class == toType) {
// 用String类型与toType比较,等于服务器发送到客户端数据。
List<Point> points = (List<Point>) value;
int count = 0;
StringBuffer sb = new StringBuffer();
sb.append("[");
for (Point point : points) {
count++;
int x = point.getX();
int y = point.getY(); sb.append("point").append(count).append(":").append("{x = ")
.append(x).append(", y=").append(y).append("}");
}
sb.append("]");
return sb.toString();
} return null;
}
}
PointConverter2.java的代码
在Struts2中添加相关字段和get/set方法,并配置属性文件:
public List<Point> getPoints() {
return points;
} public void setPoints(List<Point> points) {
this.points = points;
} private List<Point> points;
points=cn.net.bysoft.lesson3.PointConverter2
结果如下:
如果有很多Action中都有一个Poin,那局部转换就麻烦,因为要为每一个Action都编写一个属性文件,Struts2提供了全局的转换方 式,可以编写全局属性文件实现效果。属性文件命名为固定的xwork- conversion.properties,属性值等号左侧是实体类的全名,右侧是制定的转换类。例如:
cn.net.bysoft.lesson3.Point=cn.net.bysoft.lesson3.PointConverter
Struts2还提供了内置的转换类StrutsTypeConverter,他是一个抽象类,提供了两个抽象方法让我们重写:
继承这个抽象类,并重写convertFormString方法和convertToString方法,顾名思义,convertFromString是将客户端请求传递过来的字符串转换成服务端对象,而convertToString是将服务端对象转换成字符串以备发送到客户端。具体代码如下:
package cn.net.bysoft.lesson3; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; public class PointConverter3 extends StrutsTypeConverter { @Override
public Object convertFromString(Map arg0, String[] values, Class toClass) {
// 用实体的类型与toType比较,等于客户端传递到服务端数据。
List<Point> list = new ArrayList<Point>();
System.out.println(list.getClass());
// 客户端传递过来的数据为String数组,因为控件的(比如input空间)name可以有多个。
for (String value : values) {
// 解析字符串。
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 o) {
// 用String类型与toType比较,等于服务器发送到客户端数据。
List<Point> points = (List<Point>) o;
int count = 0;
StringBuffer sb = new StringBuffer();
sb.append("[");
for (Point point : points) {
count++;
int x = point.getX();
int y = point.getY(); sb.append("point").append(count).append(":").append("{x = ")
.append(x).append(", y=").append(y).append("}");
}
sb.append("]");
return sb.toString();
} }
PointConverter3.java的代码
这段代码相对于之前的代码,将两个if判断拆分成两个方法,更加优雅,并且由Starts来判断我们是从字符串转换成对象,还是从对象转换成字符串,使得代码更加健壮。
[Struts2学习笔记] -- 自定义类型转换的更多相关文章
- Struts2学习笔记(七)——类型转换
1.自动类型转换 Struts2内部提供大量类型转换器,用来完成数据类型转换问题: String和boolean.Boolean:完成字符串与布尔值之间的转换 String和char.Characte ...
- Struts2 学习笔记19 类型转换 Part1
现在来说一说类型转换,提到类型转换其实我们之前早已经用过了,在url传递参数的时候,我们传递过来的参数其实都是String类型的,在显示的时候都自动转换了,像这种简单的转换很好理解,我们要说的是,转换 ...
- Struts2 学习笔记20 类型转换part2 写自己的转换器
之前说的是调用Struts2的默认转换器,现在我们来说以下写自己的转换器,这个一般不常用,在访问不是自己写的类中可能用到.我们一点点来,因为写自己的转换器需要注意的东西还是很多的. 我们还是用之前的项 ...
- Struts2 学习笔记(概述)
Struts2 学习笔记 2015年3月7日11:02:55 MVC思想 Strust2的MVC对应关系如下: 在MVC三个模块当中,struts2对应关系如下: Model: 负责封装应用的状态,并 ...
- Struts2学习笔记⑧
今天是Struts2学习笔记的最后一篇文章了.用什么做结尾呢,这两天其实还学了很多东西,没有记录下,今天就查漏补缺一下. 文件上传与下载.FreeMarker以及昨天没做完的例子 文件上传与下载 文件 ...
- Struts2学习笔记①
Struts2 学习笔记① 所有的程序学习都从Hello World开始,今天先跟着书做一个HW的示例. Struts2是一套MVC框架,使用起来非常方便,接触到现在觉得最麻烦的地方是配置文件.我的一 ...
- Struts2学习笔记NO.1------结合Hibernate完成查询商品类别简单案例(工具IDEA)
Struts2学习笔记一结合Hibernate完成查询商品类别简单案例(工具IDEA) 1.jar包准备 Hibernate+Struts2 jar包 struts的jar比较多,可以从Struts官 ...
- iOS学习笔记-自定义过渡动画
代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...
- [原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- stl中的空间配置器
一般我们习惯的c++内存配置如下 class Foo { ... }; Foo* pf = new Foo; delete pf; 这里的new实际上分为两部分执行.首先是先用::operator n ...
- G - Shuffle'm Up
题目大意: 是一个洗牌游戏,首先给出两堆牌,s1,s2,先从s1上面拿一张牌再从s2上面拿一张牌依次往下可以洗好牌,然后把洗好的牌再分成两堆继续洗,直到这堆牌的顺序与给的顺序相同可以停止,当然如果洗不 ...
- eclipse连接远程hadoop集群开发时0700问题解决方案
eclipse连接远程hadoop集群开发时报错 错误信息: Exception in thread "main" java.io.IOException:Failed to se ...
- 用canvas把图片变成黑白相片
<!--这里没有代码--> 原来是把灰度系数分别 乘以 每个像素点的三个像素色(R,G,B)的值,然后得到的三个值加起来,再把得到的值赋值进去给每个R ,G,B. 微软的MSDN上提到的是 ...
- 关于kali安装vmware的坑,linux套路太深。
http://www.linuxidc.com/Linux/2015-08/122240.htm 但是还有些坑 安装gcc5.4.1 apt-get install gcc-5 gcc-5所在目录 / ...
- Moderate 加入空格使得可辨别单词数量最多 @CareerCup
递归题目,注意结合了memo的方法和trie的应用 package Moderate; import java.util.Hashtable; import CtCILibrary.AssortedM ...
- S3C2440 I2C总线控制
概述:话不多说,直接上图 多主机IIC总线控制(IICCON): IIC控制总线状态(IICSTAT): IIC总线地址(IICADD): IIC发送,接收总线寄存器(IICDS) IIC总线控制寄存 ...
- TCP/IP源码(59)——TCP中的三个接收队列
http://blog.chinaunix.net/uid-23629988-id-3482647.html TCP/IP源码(59)——TCP中的三个接收队列 作者:gfree.wind@gmai ...
- const常量折叠
首先来看一个例子: int main(int argc, char* argv[]) { ; int *j = (int *) &i; *j=; cout<<&i<& ...
- JDK5-枚举
1. 使用普通类模拟枚举 public class Weekday { private Weekday() {} // 私有化 public static final Weekday MONDAY = ...