目录:
- 应用场景
- 实现方法
[一]、应用场景
在实际应用中,经常会碰到表单中的日期 字符串和Javabean中的日期类型的属性自动转换,一般页面输入的日志格式为:yyyy-MM-dd ,而SpringMVC中默认不支持这样的格式转换,所以需要我们自定义数据类型的绑定才能实现这个功能。
[二]、实现方法
利用 WebBindingInitializer 注册自定义日期转换控制器。
自定义日期转换器:MyDataBinding.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package com.micmiu.demo.web.v1.utils; import java.text.SimpleDateFormat; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.WebBindingInitializer; import org.springframework.web.context.request.WebRequest; /** * 自定义日期、时间的类型绑定 * * @author <a href="http://www.micmiu.com">Michael Sun</a> */ public class MyDataBinding implements WebBindingInitializer { public void initBinder(WebDataBinder binder, WebRequest request) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); SimpleDateFormat datetimeFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); datetimeFormat.setLenient(false); binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor( dateFormat, true)); binder.registerCustomEditor(java.sql.Timestamp.class, new CustomTimestampEditor(datetimeFormat, true)); } } |
Timestamp 的实现:CustomTimestampEditor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
package com.micmiu.demo.web.v1.utils; import java.beans.PropertyEditorSupport; import java.sql.Timestamp; import java.text.SimpleDateFormat; import org.springframework.util.StringUtils; import java.text.ParseException; /** * Property editor for <code>java.sql.Timestamp</code>,<br> * supporting a custom <code>java.text.DateFormat</code>. * * @author <a href="http://www.micmiu.com">Michael Sun</a> */ public class CustomTimestampEditor extends PropertyEditorSupport { private final SimpleDateFormat dateFormat; private final boolean allowEmpty; private final int exactDateLength; public CustomTimestampEditor(SimpleDateFormat dateFormat, boolean allowEmpty) { this.dateFormat = dateFormat; this.allowEmpty = allowEmpty; this.exactDateLength = -1; } public CustomTimestampEditor(SimpleDateFormat dateFormat, boolean allowEmpty, int exactDateLength) { this.dateFormat = dateFormat; this.allowEmpty = allowEmpty; this.exactDateLength = exactDateLength; } public void setAsText(String text) throws IllegalArgumentException { if ((this.allowEmpty) && (!(StringUtils.hasText(text)))) { setValue(null); } else { if ((text != null) && (this.exactDateLength >= 0) && (text.length() != this.exactDateLength)) { throw new IllegalArgumentException( "Could not parse date: it is not exactly" + this.exactDateLength + "characters long"); } try { setValue(new Timestamp(this.dateFormat.parse(text).getTime())); } catch (ParseException ex) { throw new IllegalArgumentException("Could not parse date: " + ex.getMessage(), ex); } } } public String getAsText() { Timestamp value = (Timestamp) getValue(); return ((value != null) ? this.dateFormat.format(value) : ""); } } |
修改spring-mvc 的配置文件,添加 webBindingInitializer 属性的注入配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<!--Spring3.1 之后的自定义注解 HandlerAdapter --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer"> <bean class="com.micmiu.demo.web.v1.utils.MyDataBinding" /> </property> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" /> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="writeAcceptCharset" value="false" /> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> <value>*/*;charset=UTF-8</value> </list> </property> </bean> <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" /> <bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter" /> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean> </list> </property> </bean> |
这样就可以实现表单中的字符串自动转换为Date或者Timestamp 类型。
本文介绍到此结束@Michael Sun.
原创文章,转载请注明: 转载自micmiu – 软件开发+生活点滴[ http://www.micmiu.com/ ]
本文链接地址: http://www.micmiu.com/j2ee/spring/springmvc-binding-date/
我他妈怎么没找到这个类:
CustomTimestampEditor
Spring 4.0.5
你没有认真看完全文吧,文章中提供了 CustomTimestampEditor的code
哥哥好:
我已经解决了这个问题。使用了spring3.2提供的全局@ControllerAdvice,代码如下:
@ControllerAdvice
public class GlobalController {
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
datetimeFormat.setLenient(false);
//自动转换日期类型的字段格式
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
binder.registerCustomEditor(java.sql.Timestamp.class, new CustomTimestampEditor(datetimeFormat, true));
//防止XSS攻击
binder.registerCustomEditor(String.class, new StringEscapeEditor(true, false));
}
}
在Spring官网中,找到了相应的issue
https://jira.springsource.org/browse/SPR-7077
哥哥好:
我按照你的demo配置了我的应用。启动正常,但保存表单时出问题。还是没绑定上。
我若在Controller中自行用@InitBinder就没问题。
我找了很多,是不是和mvc:annotation-driven配置有冲突呢。我的配置是
如上配置,若只配置
也不行。
另外,我的项目默认引用的是fasterxml的jackson,为了引入
引入了codehaus的jackson
按理说不影响吧。或者去掉这个bean不引入codehaus的pom依赖也不行。
请帮忙看看,是否落下了哪些呢? 我大概看了文档,也没看太明确。
谢谢了哈。