转自:http://aokunsang.iteye.com/blog/1409505
一、数据绑定
1、全局数据绑定
第一种方式,定义一个BaseController,在里面注册一个protected void ininBinder(WebDataBinder binder){},添加注解@InitBinder。【注解式】
此种方式一般不建议使用
第二种方式,定义一个类MyBinder实现WebBindingInitializer接口,同时实现其方法public void initBinder(WebDataBinder binder, WebRequest arg1) {}。【声明式】
在spring-mvc.xml中配置
一般大家可能省事,直接写了<mvc:annotation-driven/>来激活@Controller模式,它默认会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter两个bean,它们是springMVC为@Controllers分发请求所必须的。
但是如果你想用声明式注册一个数据绑定,你需要手动注册AnnotationMethodHandlerAdapter和DefaultAnnotationHandlerMapping。
- <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean> <!-- 这个类里面你可以注册拦截器什么的 -->
- <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
- <property name="webBindingInitializer">
- <bean class="packagename.MyBinder"></bean> <!-- 这里注册自定义数据绑定类 -->
- </property>
- <property name="messageConverters">
- <list>
- <ref bean="jacksonMessageConverter"/> <!-- 注册JSON Converter-->
- </list>
- </property>
- </bean>
说明:此处org.springframework.http.converter.json.MappingJacksonHttpMessageConverter是必须配置的,否则在Controller方法前面加@ResponseBody,无法返回JSON,并报错。
同时需要引入两个jar包。jackson-core-asl.jar和jackson-mapper-asl.jar。
2、局部数据绑定
这个就简单了,直接在需要的绑定的Controller中,添加protected void ininBinder(WebDataBinder binder){ },并且添加注解@InitBinder就可以实现。例如:
- @Controller
- public class TestController{
- //日期转换器,这样就会作用到这个Controller里所有方法上
- @InitBinder
- public void initBinder(WebDataBinder binder) {
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- dateFormat.setLenient(false);
- binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
- }
- ...各种增删改查方法
- }
四、转换器
Spring提供了很多默认转换器,如StringToBooleanConverter,ObjectToStringConverter,NumberToCharacterConverter,ArrayToCollectionConverter,StringToArrayConverter,ObjectToCollectionConverter,ObjectToObjectConverter等等,如果需要自定义转换器,需要实现接口
- public interface Converter<S, T> { //S是源类型 T是目标类型
- T convert(S source); //转换S类型的source到T目标类型的转换方法
- }
我目前用到的转换器和数据绑定,基本都是对字段类型转换,两种方式都可以实现字符串到日期的转换。如:
- public class CustomDateConverter implements Converter<String, Date> {
- private String dateFormatPattern; //转换的格式
- public CustomDateConverter(String dateFormatPattern) {
- this.dateFormatPattern = dateFormatPattern;
- }
- @Override
- public Date convert(String source) {
- if(!StringUtils.hasLength(source)) {
- return null;
- }
- DateFormat df = new SimpleDateFormat(dateFormatPattern);
- try {
- return df.parse(source);
- } catch (ParseException e) {
- throw new IllegalArgumentException(String.format("类型转换失败,需要格式%s,但格式是[%s]", dateFormatPattern, source));
- }
- }
- }
配置文件有两种方式,
第一种比较简单:
- <mvc:annotation-driven conversion-service="conversionService"/>
- <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
- <property name="converters">
- <list>
- <bean class="packagename.CustomDateConverter">
- <constructor-arg value="yyyy-MM-dd"></constructor-arg>
- </bean>
- lt;/list>
- </property>
- </bean>
第二种,稍微麻烦点:
- <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
- <property name="converters">
- <list>
- <bean class="packagename.CustomDateConverter">
- <constructor-arg value="yyyy-MM-dd"></constructor-arg>
- </bean>
- </list>
- </property>
- </bean>
- <bean id="myBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
- <property name="conversionService" ref="conversionService"/>
- </bean>
- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
- <property name="webBindingInitializer" ref="myBinder"></property>
- </bean>
五、属性编辑器
1、在第三条中说了数据绑定,那么怎么能做到将String转换为Calendar或者Date呢。这里需要说的就是Spring的属性编辑器,感觉跟struts2的那个数据转换差不多。先看一段代码:
- public void initBinder(WebDataBinder binder, WebRequest arg1) {
- //这里我定义了一个匿名属性编辑器将String转为为Calendar
- binder.registerCustomEditor(Calendar.class, new PropertyEditorSupport(){
- @Override
- public void setAsText(String text) throws IllegalArgumentException {
- Calendar cal = null;
- Date date = Util.convertDate(text);
- if(date != null){
- cal = new GregorianCalendar();
- cal.setTime(date);
- }
- setValue(cal);
- }
- });
- }
说明:用binder.registerCustomEditor()注册一个属性编辑器,来进行数据的转换操作。它有2种方式。
第一种binder.registerCustomEditor(Class clz,String field,PropertyEditor propertyEditor);这种方式可以针对bean中的某一个属性进行转换操作。clz为类的class,field为bean中的某一个属性,propertyEditor为编辑器。
第二种binder.registerCustomEditor(Class clz,PropertyEditor propertyEditor)。这种方式可以针对某种数据类型进行数据转换操作。如:将传递过来的String字符串转换为Calendar,这里就需要将clz设置为Calendar.class,propertyEditor为编辑器。
2、默认spring提供了很多种属性编辑器,可以在Spring-beans-3.0.5.jar的org.springframework.beans.propertyeditors包中看到。直接使用即可,如将String转换为Date类型:
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, false));