1、ActionForm 的生命周期
ActionForm 的生命周期分两种情况
当ActionForm scope属性设置存放范围为session时:
控制器接受到请求时,从session范围中取出ActionForm实例,如果不存在创建一个新的实例,然后调用ActionForm中的reset()方法将各个参数初始化,然后把ActionForm实例保存在session中然后把客户端提交的数据封转到AcitonForm中,如果<action>的validate属性为true,则调用ActionForm的validate()方法对数据进行验证,如果存在验证错误则把请求转发给<action>的input属性把指定的web组件,ActionForm实例依然保存在session范围中;如果不存在验证错误则调用Action中的excute()方法,把ActionForm实例传递给excute()方法,然后把请求转发给其他web组件,ActionForm实例依然保存在session范围中;
当ActionForm scope属性设置存放范围为request时:
控制器接受请求时,控制器创建一个ActionForm实例并保存在request请求域中然后把客户端输入的数据封转到该ActionForm中,如果<action>的validate属性为true,则调用ActionForm的validate()方法对数据进行验证,如果存在验证错误则把请求转发给<action>的input属性把指定的web组件,ActionForm实例依然保存在当前请求范围中,重定向后该实例将丢失;如果不存在验证错误则调用Action中的excute()方法,把ActionForm实例传递给excute()方法,然后把请求转发给其他web组件,ActionForm实例依然保存在该请求范围中,重定向后该实例将丢失;
2、自定义类型转换器
struts框架可以将客户端提交的String类型的数据转换为基本数据类型并封装到FormBean中,而对于基本数据类型以外的数据类型无法进行转换封转,如Java.util.Date类型,而该类型在应用中又比较常见为应用方便我们对struts进行扩展,提供自定义的类型转换器;通过查看struts原代码我们可以看到在ActionServlet的initOther()方法中struts对基本数据类型注册了类型转换器,所以我们自定义的类型转换器只有在struts中进行注册才能够使用,如果我们将struts源码进行修改再重新打包发布使用,这样是解决问题的一中方法,但在实际应用中并不适用,我们回头查看一下在struts配置文件中我们设置的struts的启动级别为2,即容器加载工程时该servlet自启动,那么我们也同样可以自定义一个自启动的servlet来对我们自定义的类型转换器进行注册,但该servlet必须在struts启动后才能加载,因为类型转换的注册器是定义在struts内部的,同时我们要注意的是该servlet不处理任何请求所以servlet-mapping不进行定义,配置文件代码如下:
<servlet>
<servlet-name>DateConverter</servlet-name>
<servlet-class>org.zha.web.common.DateConverter</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
在struts原代码中不难发现struts类型转换器实现了org.apache.commons.beanutils.Converter接口,自定义类型转换器同样也要实现该接口,这样我们就很容易实现Date类型的转换了,代码如下:
public class DateConverter implements Converter {
private String pattern = "yyyy-MM-dd";
public DateConverter(){
}
public DateConverter(String pattern){
this.pattern = pattern;
}
/**
* @param arg0 表示目标类型
* @param arg1 表示要转换的值
* @return obj 转换后的结果
*/
public Object convert(Class arg0, Object arg1) {
Date date = null;
if(arg1 == null){
return null;
}else{
DateFormat df = new SimpleDateFormat(pattern);
try {
date = df.parse((String)arg1);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
}
另外,在实际应用中,我们可以利用静态代码块只加载一次的特点在要使用该转换器的ActionForm中用静态代码块对转换器进行注册实现方法如下:
static{
ConvertUtils.register(new DateConverter("yyyy-MM-dd HH:mm:ss"), Date.class);
}
记于2010-08-2423:34:13