通過Spring-mvc的@InitBinder注釋的方法可以對WebDataBinder做一些初始化操作。
比如設(shè)置Validator。
我一直在想能不能為每個(gè)Request或者每個(gè)Action方法單獨(dú)設(shè)置Validator。
也就是說Controller里有多個(gè)被@InitBinder標(biāo)注的方法。 在不同的Action時(shí)被分別調(diào)用。
我注意到了@InitBinder的value參數(shù),
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對象或命令調(diào)用不同的InitBinder方法。
于是我寫了下面的Controller試了一下
@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是這樣的
<form?action="doit"?method="post"?enctype="application/x-www-form-urlencoded">
????<input?type="text"?name="value1"?value="100"/>
????<input?type="submit"?name="action1"?value="Action1"/>
????<input?type="submit"?name="action2"?value="Action2"/>
</form>
我的意愿是如果畫面上,點(diǎn)擊action1按鈕擇調(diào)用initBinder1方法。 如果點(diǎn)擊action2按鈕則調(diào)用initBinder2方法。
實(shí)際上也確實(shí)是這樣的。
當(dāng)點(diǎn)擊action1時(shí),logger.info("initBinder1"); 會執(zhí)行
當(dāng)點(diǎn)擊action2是,logger.info("initBinder2"); 會執(zhí)行
是乎是可以實(shí)現(xiàn)“每個(gè)Action方法單獨(dú)設(shè)置Validator”這個(gè)目的。
但是其實(shí)并不是這樣的。
我調(diào)式進(jìn)去了InitBinder相關(guān)的源代碼InitBinderDataBinderFactory, 結(jié)果發(fā)現(xiàn)它只是在對action這個(gè)參數(shù)綁定的時(shí)候調(diào)用了上面這個(gè)方法, 對value1綁定的時(shí)候那個(gè)方法都沒有調(diào)用。而我們常常要解決的是對同一個(gè)參數(shù)對于不同的action應(yīng)用不同的Validator。
所以目前還是沒有好的方法能直接解決這個(gè)問題!
也許我們可以自己實(shí)現(xiàn)一個(gè)DataBinderFactory來解決這個(gè)問題。