[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 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- sublime text3安装SublimeREPL--解决不能运行input()的问题
原文地址:http://blog.chinaunix.net/uid-12014716-id-4269991.html 一.安装包管理器(如果已经安装可以忽略) 1.简单的安装方法:使用Ctrl+`快 ...
- 微信支付【get_brand_wcpay_request:fail_invalid appid】
微信支付授权目录一定要注意大小写 艹 如下的WXPay2 千万不要写成WxPay2了 参考地址:http://q.cnblogs.com/q/70405/ 微信支付代码下载:http://files. ...
- NOI题库1814 恼人的青蛙
1814:恼人的青蛙 总时间限制: 2000ms 单个测试点时间限制: 500ms 内存限制: 65536kB 描述 在韩国,有一种小的青蛙.每到晚上,这种青蛙会跳越稻田,从而踩踏稻子.农民在早上看到 ...
- [置顶] 【Git入门之十四】Git GUI
原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/12374495 文章都快写完了,Git GUI才浮出水面,很多人要骂我,这么方 ...
- sql给整数补零
update hs_user.clientorder a set a.stockcode = lpad(a.stockcode,6,'0') where a.market = 'SZ'
- Struts2学习笔记之s:select标签
貌似Struts2 标签都快忘光了 今天先来一发struts2的select标签: 首先从简到难,静态赋值: 1 <s:select name="user.sex" lis ...
- 如何评估oracle AWR 的在oracle 中的存储情况
如何评估oracle AWR 的在oracle 中的存储情况 如果把awr保存时间从默认的7天修改为30天,采样时间从1小时修改到更短,修改之后如何预估空间占用? ------------------ ...
- 辛星浅析跨域传输的CORS解决方式
首先我们有一个概念.那就是"同源准则",也就是same-origin policy,它要求一个站点(协议+主机+port号)来确定的脚本.XMLHttpRequest和Webso ...
- Android为ListView的Item设置不同的布局
MainActivity如下: package cc.testlistview; import java.util.ArrayList; import java.util.HashMap; impor ...
- hnsd11348tree(并查集)
Problem description A graph consists of a set of vertices and edges between pairs of vertices. Two v ...