天天看点

Spring MVC 的数据绑定、转换器、属性编辑器

转自: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。

Xml代码  

Spring MVC 的数据绑定、转换器、属性编辑器
  1. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>  <!-- 这个类里面你可以注册拦截器什么的 -->  
  2. <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>  
  3. <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
  4.     <property name="webBindingInitializer">  
  5.         <bean class="packagename.MyBinder"></bean>  <!-- 这里注册自定义数据绑定类 -->  
  6.     </property>  
  7.     <property name="messageConverters">  
  8.       <list>  
  9.         <ref bean="jacksonMessageConverter"/>    <!-- 注册JSON  Converter-->  
  10.       </list>  
  11.     </property>  
  12. </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就可以实现。例如:

Java代码  

Spring MVC 的数据绑定、转换器、属性编辑器
  1. @Controller  
  2. public class TestController{  
  3.    //日期转换器,这样就会作用到这个Controller里所有方法上  
  4.    @InitBinder    
  5.     public void initBinder(WebDataBinder binder) {    
  6.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");    
  7.         dateFormat.setLenient(false);    
  8.         binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));  
  9.     }  
  10.  ...各种增删改查方法  
  11. }  

四、转换器

 Spring提供了很多默认转换器,如StringToBooleanConverter,ObjectToStringConverter,NumberToCharacterConverter,ArrayToCollectionConverter,StringToArrayConverter,ObjectToCollectionConverter,ObjectToObjectConverter等等,如果需要自定义转换器,需要实现接口

  1. public interface Converter<S, T> { //S是源类型 T是目标类型  
  2.     T convert(S source); //转换S类型的source到T目标类型的转换方法  
  3. }

 我目前用到的转换器和数据绑定,基本都是对字段类型转换,两种方式都可以实现字符串到日期的转换。如:

Java代码  

Spring MVC 的数据绑定、转换器、属性编辑器
  1. public class CustomDateConverter implements Converter<String, Date> {  
  2.     private String dateFormatPattern;  //转换的格式  
  3.     public CustomDateConverter(String dateFormatPattern) {  
  4.             this.dateFormatPattern = dateFormatPattern;  
  5.     }  
  6.     @Override  
  7.     public Date convert(String source) {  
  8.          if(!StringUtils.hasLength(source)) {  
  9.              return null;  
  10.          }  
  11.          DateFormat df = new SimpleDateFormat(dateFormatPattern);  
  12.          try {  
  13.              return df.parse(source);  
  14.          } catch (ParseException e) {  
  15.              throw new IllegalArgumentException(String.format("类型转换失败,需要格式%s,但格式是[%s]", dateFormatPattern, source));   
  16.          }  
  17.     }  
  18. }  

 配置文件有两种方式,

第一种比较简单:

Java代码  

Spring MVC 的数据绑定、转换器、属性编辑器
  1. <mvc:annotation-driven conversion-service="conversionService"/>  
  2. <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">  
  3.  <property name="converters">  
  4.        <list>  
  5. <bean class="packagename.CustomDateConverter">  
  6.     <constructor-arg value="yyyy-MM-dd"></constructor-arg>  
  7. </bean>  
  8. lt;/list>  
  9.  </property>  
  10. </bean>  

 第二种,稍微麻烦点:

Java代码  

Spring MVC 的数据绑定、转换器、属性编辑器
  1. <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">  
  2.    <property name="converters">  
  3.     <list>  
  4.         <bean class="packagename.CustomDateConverter">  
  5.             <constructor-arg value="yyyy-MM-dd"></constructor-arg>  
  6.         </bean>  
  7.     </list>  
  8.    </property>  
  9. </bean>  
  10. <bean id="myBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">    
  11.     <property name="conversionService" ref="conversionService"/>    
  12. </bean>  
  13. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">  
  14.         <property name="webBindingInitializer" ref="myBinder"></property>  
  15. </bean>  

五、属性编辑器

1、在第三条中说了数据绑定,那么怎么能做到将String转换为Calendar或者Date呢。这里需要说的就是Spring的属性编辑器,感觉跟struts2的那个数据转换差不多。先看一段代码:

Java代码  

Spring MVC 的数据绑定、转换器、属性编辑器
  1. public void initBinder(WebDataBinder binder, WebRequest arg1) {  
  2.     //这里我定义了一个匿名属性编辑器将String转为为Calendar  
  3.         binder.registerCustomEditor(Calendar.class, new PropertyEditorSupport(){  
  4.         @Override  
  5.         public void setAsText(String text) throws IllegalArgumentException {  
  6.             Calendar cal = null;  
  7.             Date date = Util.convertDate(text);  
  8.             if(date != null){  
  9.                 cal = new GregorianCalendar();  
  10.                 cal.setTime(date);  
  11.             }  
  12.             setValue(cal);  
  13.         }  
  14.     });  
  15. }  

说明:用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类型:

Java代码  

Spring MVC 的数据绑定、转换器、属性编辑器
  1. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  2. binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, false));