ConversionSerivce 最重點的目的是將http的請求參數以什麼形式進行類型轉換,簡單來說HTTP請求都是以String的方式進行傳輸的,但是我們是入參卻是多姿多彩的數據類型,所以SpringMVC是通過ConversionSerivce進行參數的綁定轉換的。
其實定義相應的converter的思想非常簡單,首先要知道converter是處理什麼類型轉什麼類型的,其次就是做實際的轉型任務。
當然其實SpringMVC已經完成了大部分的converter了,我們這裏也是爲了SpringMVC的這一特性而已,當然不排除以後會有自定義類型的converter需要定義。
Spring支持這些實現這三種converter
1、Converter<S,T>
2、GenericeConverter
3、ConverterFactory
首先我們將<id>:<username>:<pwd>這個字符轉成一個User對象爲目標,先使用Converter<S,T>去實現:
public class StringToUserConvert implements Converter<String,User> { public User convert(String s) { String[] fields = s.split(":"); User user = new User(); user.setUserId(Integer.valueOf(fields[0])); user.setUsername(fields[1]); user.setPwd(fields[2]); System.out.println(">>>>>>>"+user.toString()); return user; } }
因爲本來SpringMVC就已經裝配了一個conversionService所以我們需要定義一個自己的conversionService然後添加我們的Converter
<bean id="myConversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.maxfunner.convert.StringToUserConvert"/> </set> </property> </bean>然後使用我們自己定義的conversionService
<mvc:annotation-driven conversion-service="myConversionService"/>
然後我們在controller嘗試使用這一轉換是否有效:
@RequestMapping("/getUserRequest.json") public @ResponseBody List<User> getUserRequest(@RequestParam("user") User user, @RequestParam("admin") User admin) { List<User> userList = new ArrayList<User>(); userList.add(user); userList.add(admin); return userList; }
相應的請求參數如下:
http://localhost:8080/springreview/user/getUserRequest.json?user=123:tony:tonypwd&admin=1:admin:adminpwd
返回的JSON
[{"userId":123,"username":"tony","pwd":"tonypwd","registerDate":null,"balance":0},{"userId":1,"username":"admin","pwd":"adminpwd","registerDate":null,"balance":0}]
需要注意的是一定要打@RequestParam註解,因爲我在測試的時候發現有點怪異,建議使用自定義converter都打上
GenericeConverter的實現方式,其實GenericeConverter是適合用於一次新定義對個類型轉換的,就是說一個GenericeConverter可以定義String ->User , int->User,String->Order,以下就是GenericeConverter的實現方式:
public class UserGenericConvert implements GenericConverter { //定義接受的轉換現在只支持String->User的轉換 public Set<ConvertiblePair> getConvertibleTypes() { Set<ConvertiblePair> pairs = new HashSet<ConvertiblePair>(); pairs.add(new ConvertiblePair(String.class, User.class)); return pairs; } //實際轉換方法 public Object convert(Object o, TypeDescriptor typeDescriptor, TypeDescriptor typeDescriptor1) { //判斷當前轉換類型,上面getConvertibleTypes定義了多個轉換,就實現多個轉換 if (typeDescriptor.getType().equals(String.class) && typeDescriptor1.getType().equals(User.class)) { String s = (String) o; String[] fields = s.split(":"); User user = new User(); user.setUserId(Integer.valueOf(fields[0])); user.setUsername(fields[1]); user.setPwd(fields[2]); System.out.println(">>>>>>>" + user.toString()); return user; } return null; } }註釋還是說的比較清晰了,然後配置XML也是差不多,就是把類換一下:
<bean id="myConversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.maxfunner.convert.StringToUserConvert"/> </set> </property> </bean>
數據化格式
有種情況就是,一般情況下用戶界面輸入的都是一些格式化的數據然後轉換過來成爲一些像date這樣的類型,格式化數據就非常有用了。其實我就用過在日期轉換裏面。當然你也可以自定義Fomartter,這裏就不多說了。但是官方也給出了比較多Fomartter的註解可以使用。但是我們需要使用org.springframework.format.support.FormattingConversionServiceFactoryBean而不是org.springframework.context.support.ConversionServiceFactoryBean作爲conversionService所以我們需要改變一下conversionService:
<bean id="myConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"/>
然後我們在User中定義格式化的annotation註解:
@DateTimeFormat(pattern = "yyyy-MM-dd") private Date registerDate;然後用戶就可以輸入2017-11-21這樣的字符串然後轉爲date了。但是這些特性我用得還是相當少的,所以也是寫下留作以後回憶之用而已。