struts2自定义类型转换器
首先,何为struts2的类型转换器?
类型转换器的作用是将请求中的字符串或字符串数组参数与action中的对象进行相互转换。
一、大部分时候,使用struts2提供的类型转换器以及OGNL类型转换机制即可满足大部分类型转换需求。如:
类User.java
package models; public class User {
private String username;
private String password; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} }
类LoginAction
package actions; import java.util.List; import models.User; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport { private User user; public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} @Override
public String execute() throws Exception {
if (getUser().getUsername().equals("yangys")
&& getUser().getPassword().equals("123")) {
return SUCCESS;
}
return ERROR;
} }
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="login page"></s:text></title>
</head>
<body>
<s:form action="login">
<s:textfield name="user.username" key="username" />
<s:password name="user.password" key="password" />
<s:submit value="login" />
</s:form>
</body>
</html>
不用做任何处理,表单中的user.username和user.password即可映射到LoginAction中的user对象上。
注:需提供相关的getter与setter
二、在特殊情况下,这种类型转换满足不了需求,比如需要把一个复杂字符串转换为一个对象。
如用户输入"huaihaizi,123"需要将huaihaizi映射到username,把123映射到password。则需要提供自定义类型转换器并将其注册到struts2中,供系统调用并完成类型转换。
为了模拟此需求,将login.jsp改为如下,通过一个user输入框输入用户名密码,以逗号分隔。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="login page"></s:text></title>
</head>
<body>
<s:form action="login">
<s:textfield name="user" key="user" />
<s:submit value="login" />
</s:form>
</body>
</html>
User.java与LoginAction.java保持不变。此时为了达到user输入框中的内容映射到user对象的username和password上,需要编写一个自定义转换器类。在OGNL项目中有一个TypeConvert接口,这个借口就是自定义类型转换器必须实现的接口,该接口定义如下。
public interface TypeConverter {
public Object convertValue(Map context, Object target, Member member,
String propertyName, Object value, Class toType);
}
实现自定义类型转换器必须实现上面的接口,但是该接口过于复杂,所以OGNL提供了实现类DefaultTypeConverter,通常都采用继承并重写DefaultTypeConverter的convertValue()方法来实现自定义类型转换器,如上需求,需要编写UserConverter.java,代码如下:
package converters; import java.util.Map; import models.User;
import ognl.DefaultTypeConverter; public class UserConverter extends DefaultTypeConverter { @Override
public Object convertValue(Map context, Object value, Class toType) {
if (toType == User.class) {
String[] params = (String[]) value;
User user = new User();
user.setUsername(params[0].split(",")[0]);
user.setPassword(params[0].split(",")[1]);
return user;
} else if (toType == String.class) {
User user = (User) value;
String userString = "<" + user.getUsername() + ","
+ user.getPassword() + ">";
return userString;
}
return null;
}
}
这里,convertValue方法就是执行类型转换逻辑的,参数value是转换前的值,toType是转换目标类型,通过判断toType来执行转换方向的逻辑代码。如此例中,toType==User.class时,即为将页面字符串转换成User类的对象,由于适应页面控件参数的通用性,页面参数统一包装成了字符串数组,如果是一个字符串,则为长度1的字符串数组。比如此例中,输入为"huaihaizi,123",则把huaihaizi赋值给user对象的username,把123赋值给user对象的password,并将此user返回即可。反之则把user对象的username和password拼接成字符串返回。
三、struts2提供了一个StrutsTypeConverter抽象类,这个类是DefaultTypeConverter的子类,将convertValue的两个转换方向拆分成了两个方法,
convertFromString(Map context,String[] values,Class toClass)
convertToString(Map context ,Object o)
逻辑更为清楚,用法与DefaultTypeConverter一致。
三、然后通过在struts2项目中注册此自定义类型转换器即可,注册此自定义类型转换器有三种方式。
1.注册局部类型转换器,局部类型转换器仅仅对某个Action的属性起作用
局部类型转换器则是在该Action同一目录下添加ActionName-convertion.properties,并在内部添加一行映射关系<propName>=<ConverterClass>。本例子中在LgoinAction.java所在包下添加LoginAction-convertion.properties文件,并在文件中添加user=converters.UserConverter即可。
2.注册全局类型转换器,全局类型转换器对所有Action的特定类型的属性都会生效
在源代码根路径下提供xwork-convertion.properties文件。并在文件中添加<propType>=<ConverterClass>。本例子中在src目录下添加xwork-convertion.properties文件,并在文件中添加models.User=converters.UserConverter即可。
3.使用JDK1.5的注解来注册类型转换器。
局部类型转换器与全局类型转换器的区别:局部类型转换器只针对局部变量进行一次性转换,比如该局部变量是个List<User>,也是在局部类型转换器中对该变量进行一次转换。如果用全局类型转换器,则该List中的每一个User都将进行一次转换。
四、处理Set集合属性的类型转换,一般情况下不建议在Action中使用Set集合属性,因为Set集合里元素是无序的,所以Struts2不能准确的将参数转换成Set集合里的元素,也不能准确的读取Set集合里的元素。除非Set集合的每个元素都有一个唯一标示,比如对于上面的User类来讲,将username做为标识,则在Action的Set<User>中不能存在两个User对象的username相同,需要重写User的equals和hashCode方法。
@Override
public int hashCode() {
// TODO Auto-generated method stub
return getUsername().hashCode();
} @Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj != null && obj.getClass() == User.class) {
User objUser = (User) obj;
if (objUser.getUsername().equals(this.getUsername())) {
return true;
}
}
return false;
}
然后在局部类型转换器注册文件中指定该Set集合元素的标识。如该Set集合为users,则上面讲过在LoginAction-conversion.properties中添加users=converters.UserConverter 即可注册该局部类型转换器,现在此行下面添加KeyProperty_users=username则可以制定users变量的唯一标识属性是username。
struts2自定义类型转换器的更多相关文章
- [JavaWeb基础] 013.Struts2 自定义类型转换器
很多时候,我们在做web开发的时候经常要用到时间的转换器,Struts2给我们提供了一种类型转换器的接口.下面我们讲讲怎么实现吧. 1.首先我们要定义一个类型转换的类,继承自com.babybus.s ...
- Struts2初学 struts2自定义类型转换器
一.问题的引出 Struts2的类型转换是基于OGNL表达式的,由于请求的参数都是字符串,而JAVA 本身属于强类型的的语言,这样就需要把请求参数字符串转换成其他类型. Struts ...
- Struts2之自定义类型转换器
Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用d ...
- Struts2框架的自定义类型转换器
前言:对于java的基本数据类型及一些系统类(如Date类.集合类),Struts2提供了内置类型转换功能,但是也有一定的限制.所以就演示出自定义类型转换器 一.应用于局部类型转换器 eg.用户登录出 ...
- [原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- struts2基础---->自定义类型转换器
这一章,我们开始struts2中自定义类型转换器的学习. 自定义类型转换器
- sruts2 自定义类型转换器
1.1.1 Struts2中自定义类型转换器:(了解) 类型转换的过程是双向的过程: JSP---->Action参数提交:String---Date. Action---->JSP ...
- 自定义类型转换器converter
作用:目前将日期转换成string,将string转换成我想要的类型 0509课件里讲 一.数据类型转换在web应用程序中,数据存在两个方向上的转换:1.当提交表单时 表单数据以字符串的形式提交 ...
- Struts(二十):自定义类型转换器
如何自定义类型转换器: 1)为什么需要自定义类型转化器?strtuts2不能自动完成字符串到所有的类型: 2) 如何定义类型转化器? 步骤一:创建自定义类型转化器的类,并继承org.apache.st ...
随机推荐
- centos解决ping unknown host的问题
当ping www.baidu.com 的时候如果出现 unknown host的提示 再ping一下IP, ping 8.8.8.8 如果此时能ping通,那么就是DNS服务器没有设置,不能解析域名 ...
- poj 2528 线段树 离散化的小技巧
题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报思路:直接搞超时+超内存,需要离散化.离散化简单的来说就是只取我们需要的值来 用,比如说区间[1000,2000],[1990,2012] ...
- 如何通过Visual Studio发布Azure应用程序
发布 Azure 云服务 使用 Azure Tools for Visual Studio,可以直接从 Visual Studio 将云服务发布到 Azure. 在发布 Azure 云服务之前,必须已 ...
- ACM2027
统计元音 Problem Description 统计每个元音字母在字符串中出现的次数. Input 输入数据首先包括一个整数n,表示测试实例的个数,然后是n行长度不超过100的字符串. Ou ...
- 枚举在c与c++中定义的不同
众所周知的,枚举是在运行期才决定枚举变量的值的,而不是像宏一样在预编译的时候就进行值得替换. 而且c标准规定: size(int) <= size(enum)<=系统所能表示的最大范围的值 ...
- lua 中pairs 和 ipairs区别
lua 中pairs 和 ipairs区别 标准库提供了集中迭代器,包括迭代文件每行的(io.lines),迭代table元素的(pairs),迭代数组元素的(ipairs),迭代字符串中单词的 (s ...
- java项目中eclipse控制台输出log4j的信息
最近做的一个hadoop项目中,用MR实现了一个比较复杂的问题,其中的日志信息都是使用的是log4j来处理的.但不知怎么控制台不输出日志信息,只能输出System.out.println()信息,这个 ...
- UVa1328 - Period(KMP找最短循环节)
题目大意 给定一个长度为n的字符串,求它的每个前缀的最短循环节 题解 白书例题~~~ "错位部分"长度为i-f[i], 如果这个前i个字符能够组成一个周期串,那么"错位& ...
- C++中字符串的结尾标志\0
\0是C++中字符串的结尾标志,存储在字符串的结尾,它虽然不计入串长,但要占一个字节的内存空间.在百度百科中查看\0词条,会有这样一句话:c/c++中规定字符串的结尾标志为'\0'.有人可能认为,在C ...
- The Basics
“Swift is a new programming language for iOS and OS X app development. Nonetheless, many parts of Sw ...