(1)概述
· 从一个HTML表单到一个Action对象,类型转换是从字符串到非字符串.
· HTTP没有”类型”的概念,每一项表单输入只可能是一个字符串或者字符串数组.在服务端,必须把String转换为特定的数据类型.
.在Struts2中把请求参数映射到action属性的工作由ParametersInterceptor负责,它是默认的defaultStack拦截器中的一员.ParametersInterceptor可以自动完成字符串到基本数据类型之间的转换.
(2)类型转换错误
~~若Action类没有实现ValidationAware接口:Struts2在遇到类型转换错误时,仍会继续调用其Action方法,就好像什么也没有发生过一样.
~~若Action类实现了 ValidationAware接口:Struts2在遇到类型转换错误时将不会继续调用其Action方法,Struts2将检查相关action元素的声明是否包含着一个name=”input”的result,如果有,struts2将把控制权转交给那个result元素,若没有result结果,Struts2将抛出一个异常.如下图所示:
(3)如何覆盖默认的错误消息
①在对应的Action类或JavaBean所在的包中新建[ActionClassName].properties文件,ActionClassName即为包含着输入字段的Action类的类名.
②在属性文件中添加如下键值对:invalid.fieldvalue.fieldName=XXX,例invalid.fieldvalue.age=非法值
注:若是自定义的类型转换器需要把类型转换失败的异常抛出,才能够使页面正常显示错误消息
(4)如果是simple主题,不会自动显示错误消息,若想显示,应操作如下步骤:
①通过debug标签可知若转换出错,则在值栈的Action(实现了ValidateAware接口)对象中有一个fieldErrors属性,该属性的类型为Map<String,List<String>>
,键:字段(属性名),值:错误消息组成的List,所以可用EL或OGNL的方式来显示错误消息:${fieldErrors.age[0]}
(5)如何自定义类型转换器
1,Why?因为Struts2不能自动完成字符串到引用类型的转换
2,How?
①开发类型转换器的类:扩展StrutsTypeConverter类,如下例子
public class DateConversion extends StrutsTypeConverter {
private DateFormat dateFormat;
public DateConversion(){
System.out.println("DateConversion...");
}
public DateFormat getDateFormat(){
if(dateFormat == null){
ServletContext servletContext = ServletActionContext.getServletContext();
String pattern = servletContext.getInitParameter("pattern");
System.out.println("pattern:"+pattern);
dateFormat = new SimpleDateFormat(pattern);
}
return dateFormat;
}
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
System.out.println("convertFromString...");
if(toClass == Date.class){
if(values != null & values.length > 0){
String value = values[0];
System.out.println("value:"+value);
try {
Date date = getDateFormat().parse(value);
return date;
} catch (ParseException e) {
// TODO Auto-generated catch block
System.out.println("转换失败");
throw new XWorkException("Could not parse date", e);
}
}
}
return values;
}
@Override
public String convertToString(Map context, Object o) {
System.out.println("converToString...");
if(o instanceof Date){
Date date = (Date)o;
String value = getDateFormat().format(date);
return value;
}
return null;
}
}
②配置类型转换器:
有两种方式:
1)基于字段的配置
·在字段所在的Model(可能是Action,可能是一个JavaBean)的包下,新建一个[ModelClassName]-conversion.properties文件.
·在该文件中输入键值对:fieldName = 类型转换器的全类名.例:birth=com.ty.exer1.converters.DateConversion
注:–>第一次使用该转换器时才创建实例; –>类型转换器是单实例的;
2)基于类型的配置
·在src下新建xwork-conversion.properties.
·在该文件中输入键值对:待转换的类型 = 类型转换器的全类名.
例:java.util.Date=com.ty.exer1.converters.DateConversion
com.ty.model.Address=com.ty.exer1.converters.AddressConversion
注:在当前Struts2应用被加载时创建实例.
(6)类型转换与复杂属性配合使用