通過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è)問題。