數據綁定應該算是spring MVC的特點之一吧~簡單易用且功能強大,極大地簡化了我們編程人員對於用戶輸入數據的接收及轉換。
早先版本的Spring中的數據綁定完全都是基於PropertyEditor的。而Spring3中引入了Converter,用來替代PropertyEditor完成類型轉換。
那么我們也依照這個順序,先來講講基於傳統的PropertyEditor來實現日期類型的數據綁定。
在Spring MVC中,我們可以通過WebDataBinder來注冊自定義的PropertyEditor,從而添加對應的請求參數綁定。有兩種方式:
1、使用@InitBinder注解@Controller中的方法 2、自定義WebBindingInitializer來提供一個全局的數據綁定規則。
1、使用@InitBinder注解
@InitBinder public void initBinder(WebDataBinder binder){ binder.registerCustomEditor(Date.class, new DateEditor()); }
public class DateEditor extends PropertyEditorSupport { @Override public void setAsText(String text) throws IllegalArgumentException { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = null; try { date = format.parse(text); } catch (ParseException e) { format = new SimpleDateFormat("yyyy-MM-dd"); try { date = format.parse(text); } catch (ParseException e1) { e1.printStackTrace(); } } setValue(date); } }
這里我們將DateEditor提出來封裝成一個類方便重用。
另外這里有個try...catch的小妙用,就是首先以"yyyy-MM-dd HH:mm:ss"的形式來解析用戶輸入的參數,若解析失敗則轉以"yyyy-MM-dd"的形式來解析。這樣的邏輯就可以同時處理"yyyy-MM-dd HH:mm:ss"和"yyyy-MM-dd"形式的日期數據,我想在一般的中文系統中,這兩種形式應該是最常用的了吧。
添加如上代碼之后,@InitBinder所在的Controller就可以自動綁定日期類型的數據了,不過這僅僅是在該Controller中生效,若想在全局范圍內生效的話,可以將@InitBinder注解所在的Controller定義為一個BaseController,其余Controller都繼承這個Controller。當然還有另外的方法,若你有興趣的話,請看2。
2、自定義WebBindingInitializer
public class MyWebBindingInitializer implements WebBindingInitializer { @Override public void initBinder(WebDataBinder binder, WebRequest request) { binder.registerCustomEditor(Date.class, new DateEditor()); } }
還是前面寫的DateEditor,這么快又見面了,只不過注冊的位置改變了,在WebBindingInitializer中注冊的PropertyEditor是在全局范圍內共享的。
不過光這樣還不夠,還要將WebBindingInitializer注入到AnnotationMethodHandlerAdapter中。
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer"> <bean class="com.**.**.**.MyWebBindingInitializer" /> </property> </bean>
完美解決問題提
測試代碼
@Controller @RequestMapping(value="/") public class BaseController { @RequestMapping(value="index") public String indexJsp(String username,Date date,Date ddate){ System.out.println(username); System.out.println(date); System.out.println(ddate); return "index"; } }
測試參數
index?username=fasdf&date=2012-12-03&ddate=2013-03-06
輸出結果:
fasdf Mon Dec 03 00:00:00 CST 2012 Wed Mar 06 00:00:00 CST 2013
參考文檔:http://blog.csdn.net/u012345283/article/details/43268081
第二種方式使用Converter
代碼如下
public class MyConverter implements Converter<String, Date> { @Override public Date convert(String source) { // TODO Auto-generated method stub SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); try { // 轉成直接返回 return simpleDateFormat.parse(source); } catch (ParseException e) { simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { return simpleDateFormat.parse(source); } catch (ParseException e1) { System.out.println("日期轉換失敗->" + this.getClass().getName()); } } // 如果參數綁定失敗返回null return null; } }
XML配置如下
<!-- 日期時間數據綁定 需要放在mvc:annotation-driven 之前 防止未掃描注入容器總- --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="****.MyConverter" /> </list> </property> </bean>
很輕松的解決問題,
3,當然Spring是非常強大的還可以使用Formatter,Formatter比Converter更適合Converter是處理任意兩類型間的轉換,而Formatter是處理字符串和另一類型之間的轉換的。
public class MyDateFormatter implements Formatter<Date> { @Override public String print(Date object, Locale locale) { // TODO Auto-generated method stub return null; } @Override public Date parse(String text, Locale locale) throws ParseException { // TODO Auto-generated method stub SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = null; try { date = format.parse(text); } catch (Exception e) { format = new SimpleDateFormat("yyyy-MM-dd"); date = format.parse(text); } return date; } }
XML配置如下:
<mvc:annotation-driven conversion-service="conversionService"/> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <set> <bean class="com.ivlo.crm.extend.MyDateFormatter"></bean> </set> </property> </bean>
不問先后順序