struts2自定义类型转换器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的注解来注册类型转换器。
以上是关于struts2自定义类型转换器的主要内容,如果未能解决你的问题,请参考以下文章
[原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器