前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。
@InitBinder用于在@Controller中標注于方法,表示為當前控制器注冊一個屬性編輯器或者其他,只對當前的Controller有效。
在使用SpringMVC的時候,經常會遇到表單中的日期字符串和JavaBean的Date類型的轉換,而SpringMVC默認不支持這個格式的轉換,需要手動配置自定義數據的綁定才能解決這個問題。
在需要日期轉換的Controller中使用SpringMVC的注解@initbinder和Spring自帶的WebDateBinder類來操作。
WebDataBinder是用來綁定請求參數到指定的屬性編輯器.? 由前臺傳到controller里的值是String類型的,當往Model里Set這個值的時候,如果set的這個屬性是個對象,Spring就會去找到對應的editor進行轉換,然后再SET進去。
-----------------------------------我是分隔線-----------------------------------
一. 問題描述:
一張表單中提交多個對象,并在后臺Controller 中精準的綁定。可對象中的參數名有的相同,后臺接收入參時無法像struts那樣jsp表單中使用Object.Param形式對表單進行精準綁定入參(struts2默認就是這種方案),因為struts2采用了OGNL,并通過棧(根對象)進行操作,棧中默認有action實例,所以無此問題。但 Struts用這種方式綁定入參犧牲了性能。
現在以前臺表單提交兩個對象為例。
User.java 和 Addr.java
public class User implements Serializable{
String id;
String name;
//get..set....
}
public class Addr implements Serializable{String id;String name;//set..get...
}
前臺JSP
<form action="/test/test" method="post"><input type="text" name="user.id" value="huo_user_id"><input type="text" name="user.name" value="huo_user_name"><input type="text" name="addr.id" value="huo_addr_id"><input type="text" name="addr.name" value="huo_addr_name"><input type="submit" value="提交">
</form>
此時 springMVC 直接進行入參,是不能接收到參數的。
二. 解決思路
用 @InitBinder 注解作參數綁定。前臺表單中name屬性仍然使用Object.Param形式傳入。
(另一種解決思路:擴展spring的HandlerMethodArgumentResolver以支持自定義的數據綁定方式。)
@InitBinder("user")public void initBinderUser(WebDataBinder binder) {binder.setFieldDefaultPrefix("user.");}
@InitBinder() 的value,用于指定命令/表單屬性或請求參數的名字,符合該名字的將使用此處的DataBinder,如我們的@ModelAttribute("user1") User user1 將使用@InitBinder("user1")指定的DataBinder綁定;如果不指定value值,那么所有的都將使用。
DataBinder.setFieldDefaultPrefix 是設置參數的前綴,如我們的是"user1.",此處不能少了".",
此方式的缺點:
1、不支持Path variable的綁定,如/test1/{user1.id}這種情況的綁定;
2、不支持如集合/數組的綁定;
三 問題解決
@Controller
@RequestMapping("/test")
public class TestController {
// 綁定變量名字和屬性,參數封裝進類@InitBinder("user")public void initBinderUser(WebDataBinder binder) {binder.setFieldDefaultPrefix("user.");}// 綁定變量名字和屬性,參數封裝進類@InitBinder("addr")public void initBinderAddr(WebDataBinder binder) {binder.setFieldDefaultPrefix("addr.");}@RequestMapping("/test")@ResponseBodypublic Map<String,Object> test(HttpServletRequest request,@ModelAttribute("user") User user,@ModelAttribute("addr") Addr addr){Map<String,Object> map=new HashMap<String,Object>();map.put("user", user);map.put("addr", addr);return map;}
就一個@InitBinder 就可以解決了。
另外可以通過DataBinder完成如下幾件事情:
1、binder.setAllowedFields("id")??: 設置允許的字段,比如我只想設置id,那么可以調用這個方法,那么其他屬性會忽略;2、binder.setDisallowedFields("id") : 設置不允許的自動,比如我不想設置id,那么可以調用此方法,這個屬性將不設置;3、binder.setRequiredFields() : 表示哪些字段是必填的;4、binder.setValidator() :設置自定義的驗證器,如果如JSR-303不適合,可以使用這個。
完整例子:
?
兩個對象
public class User implements Serializable{
String id;
String name;
//get..set....
}
public class Addr implements Serializable{String id;String name;//set..get...
}
jsp
<form action="/test/test" method="post"><input type="text" name="user.id" value="huo_user_id"><input type="text" name="user.name" value="huo_user_name"><input type="text" name="addr.id" value="huo_addr_id"><input type="text" name="addr.name" value="huo_addr_name"><input type="submit" value="提交">
</form>
Controller
@Controller
@RequestMapping("/test")
public class TestController {
// 綁定變量名字和屬性,參數封裝進類@InitBinder("user")public void initBinderUser(WebDataBinder binder) {binder.setFieldDefaultPrefix("user.");}// 綁定變量名字和屬性,參數封裝進類@InitBinder("addr")public void initBinderAddr(WebDataBinder binder) {binder.setFieldDefaultPrefix("addr.");}@RequestMapping("/test")@ResponseBodypublic Map<String,Object> test(HttpServletRequest request,@ModelAttribute("user") User user,@ModelAttribute("addr") Addr addr){Map<String,Object> map=new HashMap<String,Object>();map.put("user", user);map.put("addr", addr);return map;}
---------------------?
轉自:
https://blog.csdn.net/qq_24505127/article/details/54236583?
https://blog.51cto.com/simplelife/1919597
?
另關于類型轉換見另一文章: SpringMVC注解 @initbinder 解決類型轉換問題
?