关于spring-mvc的InitBinder注解的参数

通过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来解决这个问题。


你可能感兴趣的:(InitBinder)