Struts2自定义类型转换:
从前台接受到的类型全部是字符串,Struts2自带的一些基本类型转换有时不能满足我们的特别需要,如:日期字符串输入格式,还有一些自定义的类,直接传到后台,我们需要一些自己的转换器:
例:
我有一个Point类型:
package cn.jnit.bean;
public class Point {
private Integer x;
private Integer y;
public Point() {
}
public Point(Integer x, Integer y) {
this.x = x;
this.y = y;
}
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
public Integer getY() {
return y;
}
public void setY(Integer y) {
this.y = y;
}
}
测试类型转换器:我前台的struts表单
<s:form action="point" method="post">
<s:textfield name="point"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
<%-- <s:property value="point"/> --%>
表单对应的Action:
package cn.jnit.action;
import cn.jnit.bean.Point;
import com.opensymphony.xwork2.ActionSupport;
public class ConvertAcion extends ActionSupport{
private Point point;
@Override
public String execute() throws Exception {
System.out.println(point.getX());
System.out.println(point.getY());
return SUCCESS;
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
}
我们找到xwork-core-2.2.1.jar核心包里com.opensymphony.xwork2里的com.opensymphony.xwork2.conversion里的TypeConverter.class里的com.opensymphony.xwork2.conversion.TypeConverter接口:实现TypeConverter接口的类里有DefaultTypeConverter类,我们可以看到继承自DefaultTypeConverter类的类里有一个抽象类StrutsTypeConverter,我们自定义的类就继承自StrutsTypeConverter,然后会重写两个方法:
1:把从前台传来的字符串数据封装成对象
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {}
2:把后台对象再转换成字符串数据回显到前台
@Override
public String convertToString(Map context, Object o) {}
那么我的自定义转换类:
package cn.jnit.convert;
import java.util.Arrays;
import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;
import com.opensymphony.xwork2.conversion.TypeConversionException;
import cn.jnit.bean.Point;
public class MyConvert extends StrutsTypeConverter {
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
/* System.out.println("--------------------------Map---------------");
for (Object obj : context.keySet()) {
System.out.println(obj);
}
System.out.println("-------------------------------");
System.out.println(Arrays.toString(values));
System.out.println("-----------class--------------------");
System.out.println(toClass);
System.out.println("-------------------------------------------");*/
Point p=new Point();
System.out.println(values[0]);
String string =values[0].split(",")[0];
if(!(values[0].length()>0&&values[0].matches("\\d{2,5},\\d{2,5}"))){
//如果前台页面传进来的值与我自定义的类型转换方法里拆分的值不匹配则抛出异常
throw new TypeConversionException();
}
p.setX(Integer.valueOf(values[0].split(",")[0]));
p.setY(Integer.valueOf(values[0].split(",")[1]));
// TODO Auto-generated method stub
return p;
}
@Override
public String convertToString(Map context, Object o) {
Point p=(Point) o;
return p.getX()+","+p.getY();
}
}
由于用的是Struts自带的表单,会在提交的标签上自动加上错误信息,如果用的是HTML表单,那么需要加上<s:fielderror></s:fielderror>才会显示错误信息(建议用struts自带的表单)。
但是错误提示信息是strut2自带的英文提示信息,如果想要换成自己的错误提示信息,那么我们有两种选择:
第一种是:应用于全局范围的类型转换器,具体为:
首先我们需要在struts.xml里加上:
<constant name="struts.custom.i18n.resources" value="message"></constant>
的信息,因为默认情况下,所有类型转换的错误都是通用的i18n消息键
xwork-default.invalid.fieldvalue来报告错误信息的。然后,我们需要在src下创建一个message.properties文件,然后里面的简直对为:name:xwork.default.invalid.fieldvalue value:字段“{0}”的值无效(用Properties视图下,如果用Source视图下会显示为:xwork.default.invalid.fieldvalue=\u5B57\u6BB5\u201C{0}\u201D\u7684\u503C\u65E0\u6548
)
第二种是:应用特定类的类型转换器,具体为:
在Action包里,创建一个和Action同名的properties文件,里面的name=value为:
Invalid.fieldvalue.point=point 转换错误,
如果这个类是自定义类型,需要再加上一个:Action同名-conversion.properties的文件,里面的name值为point,value值为:自定义的类型转换器的全类名,如:point=cn.jnit.convert.MyConvert
最后切记所有的properties文件名一个字母都不能错,不然没有效果!