通过Spring-mvc的@InitBinder注释的方法可以对WebDataBinder做一些初始化操作。
比如设置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试了一下
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
@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是这样的
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
<
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
>
我的意愿是如果画面上,点击action1按钮择调用initBinder1方法。 如果点击action2按钮则调用initBinder2方法。
实际上也确实是这样的。
当点击action1时,logger.info("initBinder1"); 会执行
当点击action2是,logger.info("initBinder2"); 会执行
是乎是可以实现“每个Action方法单独设置Validator”这个目的。
但是其实并不是这样的。
我调式进去了InitBinder相关的源代码InitBinderDataBinderFactory, 结果发现它只是在对action这个参数绑定的时候调用了上面这个方法, 对value1绑定的时候那个方法都没有调用。而我们常常要解决的是对同一个参数对于不同的action应用不同的Validator。
所以目前还是没有好的方法能直接解决这个问题!
也许我们可以自己实现一个DataBinderFactory来解决这个问题。