天天看點

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));