传统的类型转换。(略)
Struts2中提供了内置的基本的类型转换器,可以实现基本类型的自动转换,包括:
Integer, Float, Double, Decimal
Date and Datetime
Arrays and Collections
Enumerations
Boolean
BigDecimal
基于OGNL(对OGNL暂时不熟悉)的类型转换:
以一个User类为例:
public class User {
private String name;
private String pass; public User() {
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getPass() {
return pass;
} public void setPass(String pass) {
this.pass = pass;
}
}
假设在Action类中有一个字段类型为【private User user;】,那么在以该Action为目标地址的form表单中可以设置提交项的
name=“user.name”/name="user.pass",在表单提交的时候就会自动转换为对应的属性值。需要注意的是在User的定义中必须有一个
无参的该类的构造器,该机制实际上是创建了一个User的对象,然后把表单中提交的对应的属性值通过对应的set方法赋值给该对象,因此
还必须要有对应属性的setXxx方法。
对于map类型的字段类型【Map<String, User> user;】,同样的表单中的格式:name=“user['one'].name”/name="user['one'].pass";
对于list类型的字段类型【List User user;】(在学习时,笔者感觉list和数组类似),对应的表单中的格式:name=“use[0].name”/name="user[0].pass"。
那么如果我们想把字符串“Tom,1111”转换为一个User对象呢,就需要我们自己为复合对象自定义类型转化器了。
Struts2的类型转换器也是基于OGNL实现的,在OGNL项目中提供了一个TypeConverter接口来完成类型转换,该接口是我们编写自定
义类型转换器所必须要实现的接口。如大多数情况一样,java在提供接口的时候往往也有它默认的实现类来简化我们的工作。
TypeConverter接口的实现类是DefaultTypeCounter,我们实现自己自定义的类型转换器需要重写DefaultTypeCounter里面的
converValue()方法,方法原型为:
关于如何在ecplise中查看各类jar文件的源代码,可以参考:http://jingyan.baidu.com/article/454316ab596470f7a7c03aab.html
public Object convertValue(Map<String, Object> context, Object value, Class toType) {
return convertValue(value, toType);
}
方法的参数比较容易理解,context是与Action有关的上下文信息,暂且不用管它,只需要知道value是要转换的值,toType是要转换成
的目标类型的Class类型??这里详细了解的话可以参考java反射的相关教程,例如:要转成String类型,那么toType就是String.class;
下面来看对应于User类的自定义转换器UserConverter的实现:
import java.util.Map;
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter; public class UserConverter extends DefaultTypeConverter {
@Override
public Object convertValue(Map<String, Object> context, Object value,
Class toType) {
if (toType == User.class) {
String[] params = (String[]) value;
User user = new User();
String[] userValues = params[0].split(",");
user.setName(userValues[0]);
user.setPass(userValues[1]);
return user;
} else if (toType == String.class) {
User user = (User) value;
return "<" + user.getName() + "," + user.getPass() + ">";
}
return null;
}
}
在上面的代码中我们使用一个字符串数组类接收value的值,是为了考虑到各方面的情况而采取的办法,不必太纠结于此。
现在我们有了自己定义的类型转换类,那么怎么才能真正实现当用户请求时实现类型转换呢,在这里从该转换类的作用范围角度考虑,类
型转换有两种类型,一种是局部类型转换器,一种是全局类型转换器。这两种转换器都是通过资源文件的形式联系到我们的项目中的。
@1,局部类型转换器
文件名称:"ActionName-conversion.properties"。ActionName是需要转换的属性字段所在的Action类的名字,后面的字符串
为固定格式。
文件内容:“key=value”的形式,需要转换的属性字段(不是类型)=自定义转换类的全限定名(包名+类名)。例如:user=com.home.UserConverter
文件路径:与对应Action的class文件在同一路径,一般直接将其放在对应的Action的java文件路径下即可,那末在编译后也会将其
和.class文件编译到同一路径下。
作用范围:只对指定Action的指定属性有效。
@2,全局类型转换器
文件名称:“xwork-conversion.properties”。均为固定格式。
文件内容:“key=value”的形式,需要转换为的复合类型的全限定名=自定义转换类的全限定名(包名+类名)。例如:com.home.User=com.home.UserConverter。
文件路径:只需要放到src目录下即可。
作用范围:对指定类型的所有属性均有效。