struts1日期转换处理
- 问题场景
最近在维护公司旧的系统(用的struts1框架)的时候,在日期处理的时候,我将日期设定为Date类型,结果报以下错误:
1 javax.servlet.ServletException: BeanUtils.populate 2 at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:495) 3 at org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:816) 4 at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:203) 5 at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196) 6 at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) 7 at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 8 at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 9 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269) 10 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) 11 at com.ist.common.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:366) 12 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) 13 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) 14 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) 15 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172) 16 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 17 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) 18 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108) 19 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174) 20 at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:837) 21 at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:640) 22 at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1287) 23 at java.lang.Thread.run(Thread.java:662)
后来查询资料明白了原来是类型转换错误,由于Struts默认是不支持自动将网页POST的数据自动转化成 Date型数据,所以,很多程序员就直接在ActionForm当中直接使用String,然后在Action当中再进行字符串跟日期数据的处理。但是这样感觉又不太好,数据库类型为Date类型,而在form中确实用String。
- 解决办法
同样在struts中的form中如果有int,float,double,Integer,Float,Double等基本类型,是不会报这样的错误的。网页POST过来的所有数据都是String类型,但是Struts内部有一个类型转换器,能够自动地将String类型转换成为int,float,double,Integer,Float,Double等类型。那继承Struts内部有这些转换器,那我们是否可以对其进行扩展?答案是可以的,Struts的Converter框架很好地支持了这一点。
日期类型转换器如下:
1 /** 2 * 3 * 日期转换对象,使用该转换器,在BaseForm当中做一下注册,系统自动地帮助字符的日期表示转换为java.util.Date对象. 4 * @author zizz. 5 * Create Time:2006-9-11 19:11:47. 6 */ 7 publicclass DateConverter implements Converter{ 8 /** 9 * 日期格式化对象. 10 */ 11 privatestatic SimpleDateFormat df=new SimpleDateFormat(); 12 13 /** 14 * 模式集合. 15 */ 16 privatestatic Set<String> patterns =new HashSet<String>(); 17 //注册一下日期的转换格式 18 static{ 19 DateConverter.patterns.add("yyyy-MM-dd"); 20 DateConverter.patterns.add("yyyy-MM-dd HH:mm"); 21 DateConverter.patterns.add("yyyy-MM-dd HH:mm:ss"); 22 DateConverter.patterns.add("yyyy/MM/dd HH:mm:ss"); 23 } 24 25 /** 26 * 日期转换器. 27 * @param type Class 28 * @param value Object 29 * return Date Object. 30 */ 31 public Object convert(Class type,Object value){ 32 if(value== null){ 33 return null; 34 }elseif(value instanceof String){ 35 Object dateObj = null; 36 Iterator it = patterns.iterator(); 37 while(it.hasNext()){ 38 try{ 39 String pattern =(String)it.next(); 40 df.applyPattern(pattern); 41 dateObj = df.parse((String)value); 42 break; 43 }catch(ParseException ex){ 44 //do iterator continue 45 } 46 } 47 return dateObj; 48 }else{ 49 return null; 50 } 51 } 52 }
自定义的日期转换工作必须先做注册才能使用,注册我们可以将其放在ActionForm当中。使用以下代码进行注册:
ConvertUtils.register(new DateConverter(), Date.class);