在用struts1框架编写程序的时候,在收集表单数据的时候,可能会遇到收集缺失,原因可能是格式不匹配,例如jsp页面的表单数据都是String类型,但是真正的ActionFrom可能是java.util.date类型!在这种情况下,Struts1是不能够完成从String类型到java.util.date类型的转换的!也就不能实现表单数据的收集
这就需要我们自己定义一个转换器,然后注册到struts1的转换器中。为了更好了理解编写转换器,我们先来看看Struts1的转换的工作原理
从前面的Struts1框架二之项目执行流程我们可以看出,我们的所有的.do请求都是交给ActionServlet进行处理的,里面有一个方法叫做initOther(),我们来看看这个方法做了哪些事情
protected void initOther() throws ServletException {
//这个方法,大概就是往struts1的转换器集合中添加转换器
if (convertNull) {
ConvertUtils.deregister();——————————————– ——看详细讲解1—————————
//下面这些方法,是标明你的类型对应的是什么转换器,如BigDecimal.class对应的是new BigDecimalConverter(null)转换器
ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);
ConvertUtils.register(new BigIntegerConverter(null), BigInteger.class);
ConvertUtils.register(new BooleanConverter(null), Boolean.class);
ConvertUtils.register(new ByteConverter(null), Byte.class);
ConvertUtils.register(new CharacterConverter(null), Character.class);
ConvertUtils.register(new DoubleConverter(null), Double.class);
ConvertUtils.register(new FloatConverter(null), Float.class);
ConvertUtils.register(new IntegerConverter(null), Integer.class);
ConvertUtils.register(new LongConverter(null), Long.class);
ConvertUtils.register(new ShortConverter(null), Short.class);
}
}
————————————————————– ——看详细讲解1———————————————————
这个方法是一个静态的方法,里面封装了一些基本的转换机制到真正类型的转换,如new BigDecimalConverter()这个转换器对应的是转换为BigDecimal.class类型的数据
converters调用的方法我们可以推测出,它是一个集合类型private static FastHashMap converters = new FastHashMap();
public static void deregister() {
boolean booleanArray[] = new boolean[0];
byte byteArray[] = new byte[0];
char charArray[] = new char[0];
double doubleArray[] = new double[0];
float floatArray[] = new float[0];
int intArray[] = new int[0];
long longArray[] = new long[0];
short shortArray[] = new short[0];
String stringArray[] = new String[0];
converters.clear();
converters.put(BigDecimal.class, new BigDecimalConverter());
converters.put(BigInteger.class, new BigIntegerConverter());
converters.put(Boolean.TYPE, new BooleanConverter(defaultBoolean));
converters.put(Boolean.class, new BooleanConverter(defaultBoolean));
converters.put(booleanArray.getClass(),
new BooleanArrayConverter(booleanArray));
converters.put(Byte.TYPE, new ByteConverter(defaultByte));
converters.put(Byte.class, new ByteConverter(defaultByte));
converters.put(byteArray.getClass(),
new ByteArrayConverter(byteArray));
converters.put(Character.TYPE,
new CharacterConverter(defaultCharacter));
.....
.....
.....
}
那么initOther方法又在哪里被调用了呢,答案是在ActionServlet的init()方法里面被调用了。我们又知道ActionServlet是一个HttpServlet,所以在该ActionServlet被初始化的时候,系统就会自动调用该init方法,这样系统为我们提供的转换器就可以自动执行到
public class ActionServlet extends HttpServlet {
public void init() throws ServletException {
initInternal();
initOther();
initServlet();
}
}
那么问题来了,系统在什么时候通过ActionForm里面的属性调用相应的转换器的呢?
我猜测是在系统封装表单数据的时候,也就是在processpopulate方法里面,但是我并没有找到源码,如果哪位大神找到了,请发送QQ信息到:819537628。知识因分享而收获更多
我们了解到了,一个系统是如何保存类型转换器与如何类型转换器的工作原理,那我们怎么自定义一个转换器呢?
1、首先定义一个转换器类,要实现Converter接口,重写convert方法.
2、然后使用ConvertUtils.register();静态方法注册自定义的转换器到ConvertUtils里面去
3、问题是什么时候注册呢?
原则就是在执行表单收集前将表单收集器注册到ConvertUtils里面就行了,或者在表单页面显示之前实现格式转换就行了
1、使用servlet里面的init方法,并设置该servlet类在服务器一启动就创建实例对象
2、使用ServletContextListener监听器,调用contextInitialized方法实现注册
3、使用过滤器,调用doFilter方法实现注册
4、 使用自定义标签,然后在页面实现之前实现格式的转换
5、实现PlugIn,实现init方法实现转换器的注册
6、继承ActionServlet,重写initOther()方法,在里面实现自定义转换器的注册
附件里有上述6种转换器的实现源码
转载请标明出处
感谢苏波老师的指导
个人见解、错误请指出!请莫怪