比如設置Validator。
我一直在想能不能為每個Request或者每個Action方法單獨設置Validator。
也就是說Controller里有多個被@InitBinder標注的方法。 在不同的Action時被分別調用。
我注意到了@InitBinder的value參數,
api docs里是這樣描述的:
The names of command/form attributes and/or request parameters that this init-binder method is supposed to apply to.
Default is to apply to all command/form attributes and all request parameters
processed by the annotated handler class. Specifying model attribute names or
request parameter names here restricts the init-binder method to those specific
attributes/parameters, with different init-binder methods typically applying to
different groups of attributes or parameters.
是乎是可以針對不同的Form對象或命令調用不同的InitBinder方法。
于是我寫了下面的Controller試了一下
public?class?HomeController?{
????
????private?static?final?Logger?logger?=?LoggerFactory.getLogger(HomeController.class);
????
????@InitBinder("action1")
????public?void?initBinder1(WebDataBinder?binder){
????????logger.info("initBinder1");
????}
????
????@InitBinder("action2")
????public?void?initBinder2(WebDataBinder?binder){
????????logger.info("initBinder2");
????}
????
????/**
?????*?Simply?selects?the?home?view?to?render?by?returning?its?name.
?????*/
????@RequestMapping(value?=?"/",?method?=?RequestMethod.GET)
????public?String?home(Model?model)?{????????
????????
????????Date?date?=?new?Date();
????????DateFormat?dateFormat?=?DateFormat.getDateTimeInstance(DateFormat.LONG,?DateFormat.LONG);
????????
????????String?formattedDate?=?dateFormat.format(date);
????????
????????model.addAttribute("serverTime",?formattedDate?);
????????
????????return?"home";
????}
????
????/**
?????*?Simply?selects?the?home?view?to?render?by?returning?its?name.
?????*/
????@RequestMapping(value?=?"/doit",?method?=?RequestMethod.POST,?params="action1")
????public?String?doit1(@RequestParam("value1")?int?value1,
????????????@RequestParam("action1")?String?action,?Model?model)?{????????
????????logger.info("value1={}",value1);
????????
????????Date?date?=?new?Date();
????????DateFormat?dateFormat?=?DateFormat.getDateTimeInstance(DateFormat.LONG,?DateFormat.LONG);
????????
????????String?formattedDate?=?dateFormat.format(date);
????????
????????model.addAttribute("serverTime",?formattedDate?);
????????
????????return?"home";
????}
????
????/**
?????*?Simply?selects?the?home?view?to?render?by?returning?its?name.
?????*/
????@RequestMapping(value?=?"/doit",?method?=?RequestMethod.POST,?params="action2")
????public?String?doit2(@RequestParam("value1")?int?value1,
????????????@RequestParam("action2")?String?action,?Model?model)?{????????
????????logger.info("value1={}",value1);
????????
????????Date?date?=?new?Date();
????????DateFormat?dateFormat?=?DateFormat.getDateTimeInstance(DateFormat.LONG,?DateFormat.LONG);
????????
????????String?formattedDate?=?dateFormat.format(date);
????????
????????model.addAttribute("serverTime",?formattedDate?);
????????
????????return?"home";
????}
}
畫面上的Form是這樣的
????<input?type="text"?name="value1"?value="100"/>
????<input?type="submit"?name="action1"?value="Action1"/>
????<input?type="submit"?name="action2"?value="Action2"/>
</form>
我的意愿是如果畫面上,點擊action1按鈕擇調用initBinder1方法。 如果點擊action2按鈕則調用initBinder2方法。
實際上也確實是這樣的。
當點擊action1時,logger.info("initBinder1"); 會執行
當點擊action2是,logger.info("initBinder2"); 會執行
是乎是可以實現“每個Action方法單獨設置Validator”這個目的。
但是其實并不是這樣的。
我調式進去了InitBinder相關的源代碼InitBinderDataBinderFactory, 結果發現它只是在對action這個參數綁定的時候調用了上面這個方法, 對value1綁定的時候那個方法都沒有調用。而我們常常要解決的是對同一個參數對于不同的action應用不同的Validator。
所以目前還是沒有好的方法能直接解決這個問題!
也許我們可以自己實現一個DataBinderFactory來解決這個問題。