一、 基于OGNL的类型转换器
Struts2的类型转换器都需要实现一个TypeConverter接口,该接口位于ognl.jar包内,也是就Struts2框架的转换器使用了OGNL技术。该接口定义了一个convertValue()方法,实现该接口的类型转换器实现类都需要重写该方法来进行类型转换。OGNL还提供了一个实现TypeConverter接口的类DefaultTypeConverter,开发者只要继承该类,就可以开发类型转换器的实现类。
DefaultTypeConverter类的子类需要重写convertValue()方法,来实现字符串类型与复合类型之间的双向转换。convertValue()方法有三个参数:Map context:该参数为类型转换环境的上下文内容;Object value:该参数为需要转换的参数;Class toType:该参数指的是转换目标的类型。 以下为示例:
public class PointConverter extends DefaultTypeConverter {
public Object convertValue(Map context,Object value,Class toType){
System.out.println("正在转换...");
if(toType==Point.class){
String[] p=(String[])value;
Point point=new Point();
String[] pp=p[0].split(",");
point.setX(pp[0]);
point.setY(pp[1]);
return point;
}
else if(toType==String.class){
Point point=(Point) value;
return "<"+point.getX()+","+point.getY()+">";
}
return null;
}
注意:可以看到,convertValue()方法是通过toType的类型判断来实现双向转换的。
二、 基于Struts2的类型转换器
Struts2框架提供了一个类型转换器的StrutsTypeConverter抽象类,开发者可以继承该类来开发自定义的类型转换器实现类。 该抽象类实际上继承了DefaultTypeConverter类,在该类的基础上进行了简化。StrutsTypeConverter抽象类是Struts2框架中类型转换器的基础,该类中提供了两个抽象方法,这两个抽象方法分别实现“form字符串参数-Struts复合类型”之间的双向转换。 示例代码如下:
public class PointConverter2 extends StrutsTypeConverter {
@Override
//定义convertFromString方法
public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
// TODO Auto-generated method stub
System.out.println("正在转换:从字符串转换到复合类型...");
Point point=new Point();
String[] pp=arg1[0].split(",");
point.setX(pp[0]);
point.setY(pp[1]);
return point;
}
@Override
//定义convertToString方法
public String convertToString(Map arg0, Object arg1) {
// TODO Auto-generated method stub
Point point=(Point) arg1;
return "<"+point.getX()+","+point.getY()+">";
}
}
三、 注册自定义类型转换器
在Struts2框架中使用自定义类型转换器需要注册,这样在处理用户请求的时候系统才知道使用哪个类型转换器进行转换。
1、 注册局部类型转换器
局部类型转换器的作用范围为Action范围。注册局部类型转换器需要建立一个命名规则为ActionName-conversion.properties的属性文件,该属性文件保存在与Action类文件相同的目录下。ActionName就是使用类型转换器的Action实现类的类名,而后面的-conversion.properties是固定的格式。该文件是一个标准的属性文件,内容为标准的Key-Value格式,该键值对定义如下:
propertyName=类型转换器
例如:PointAction-conversion.properties属性文件的内容如下:
p=ch6.PointConverter
2、 注册全局类型转换器
注册一个全局类型转换器,需要建立一个xwork-conversion.properties属性文件,该文件需要保存在class路径的根目录下,如WEB-INF/classes。该文件同样由多个标准的Key-Value键值对组成,其内容定义为“复合类型-对应的类型转换器”,其中复合类型就是Action中需要类型转换的类型属性,对应的类型转换器就是转换该复合类型的对应转换器。
示例:xwork-conversion.properties文件内容如下:
ch6.Point=ch6.PointConverter
四、 数组属性类型转换器和集合属性类型转换器
1、 数组属性类型转换器示例:
public class ArrayPointConverter extends StrutsTypeConverter {
@Override
public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
if(arg1.length>1){
Point[] result=new Point[arg1.length];
for(int i=0;i<arg1.length;i++){
Point point=new Point();
String[] temp=arg1[i].split(",");
point.setX(temp[0]);
point.setY(temp[1]);
result[i]=point;
}
return result;
}
else{
Point point=new Point();
String[] pp=arg1[0].split(",");
point.setX(pp[0]);
point.setY(pp[1]);
return point;
}
}
@Override
public String convertToString(Map arg0, Object arg1) {
if(arg1 instanceof Point){
Point point=(Point) arg1;
return "<"+point.getX()+","+point.getY()+">";
}
else if(arg1 instanceof Point[]){
Point[] point=(Point[])arg1;
String result="[";
for(Point p:point){
result+="<"+p.getX()+","+p.getY()+">";
}
return result+"]";
}
else{
return null;
}
}
}
2、 集合属性类型转换器示例:
public class ListPointConverter extends StrutsTypeConverter{
@Override
public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
if(arg1.length>1){
List<Point> result=new ArrayList<Point>();
for(int i=0;i<arg1.length;i++){
Point point=new Point();
String[] temp=arg1[i].split(",");
point.setX(temp[0]);
point.setY(temp[1]);
result.add(point);
}
return result;
}
else{
Point point=new Point();
String[] pp=arg1[0].split(",");
point.setX(pp[0]);
point.setY(pp[1]);
return point;
}
}
@Override
public String convertToString(Map arg0, Object arg1) {
if(arg1 instanceof Point){
Point point=(Point) arg1;
return "<"+point.getX()+","+point.getY()+">";
}
else if(arg1 instanceof List){
List<Point> point=(List<Point>)arg1;
String result="[";
for(Point p:point){
result+="<"+p.getX()+","+p.getY()+">";
}
return result+"]";
}
else{
return null;
}
}
}