@ControllerAdvice 的介绍及三种用法

转载

@ControllerAdvice 的介绍及三种用法

浅析@ControllerAdvice

首先,ControllerAdvice本质上是一个Component,因此也会被当成组建扫描,一视同仁,扫扫扫。

ControllerAdvice.class

然后,我们来看一下此类的注释:

这个类是为那些声明了(@ExceptionHandler@InitBinder@ModelAttribute注解修饰的)方法的类而提供的专业化的@Component , 以供多个 Controller类所共享。

说白了,就是aop思想的一种实现,你告诉我需要拦截规则,我帮你把他们拦下来,具体你想做更细致的拦截筛选和拦截之后的处理,你自己通过@ExceptionHandler@InitBinder@ModelAttribute这三个注解以及被其注解的方法来自定义。

在这里插入图片描述

初定义拦截规则:

ControllerAdvice 提供了多种指定Advice规则的定义方式,默认什么都不写,则是Advice所有Controller,当然你也可以通过下列的方式指定规则
比如对于 String[] value() default {} , 写成@ControllerAdvice("org.my.pkg") 或者 @ControllerAdvice(basePackages="org.my.pkg"), 则匹配org.my.pkg包及其子包下的所有Controller,当然也可以用数组的形式指定,如:@ControllerAdvice(basePackages={"org.my.pkg", "org.my.other.pkg"}), 也可以通过指定注解来匹配,比如我自定了一个 @CustomAnnotation 注解,我想匹配所有被这个注解修饰的 Controller, 可以这么写:@ControllerAdvice(annotations={CustomAnnotation.class})

还有很多用法,这里就不全部罗列了。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
<span class="token annotation punctuation">@AliasFor</span><span class="token punctuation">(</span><span class="token string">"basePackages"</span><span class="token punctuation">)</span>
String<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">default</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@AliasFor</span><span class="token punctuation">(</span><span class="token string">"value"</span><span class="token punctuation">)</span>
String<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">basePackages</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">default</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">;</span>

Class<span class="token operator">&lt;</span><span class="token operator">?</span><span class="token operator">&gt;</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">basePackageClasses</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">default</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">;</span>

Class<span class="token operator">&lt;</span><span class="token operator">?</span><span class="token operator">&gt;</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">assignableTypes</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">default</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">;</span>

Class<span class="token operator">&lt;</span><span class="token operator">?</span> <span class="token keyword">extends</span> <span class="token class-name">Annotation</span><span class="token operator">&gt;</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">annotations</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">default</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

1.处理全局异常

@ControllerAdvice 配合 @ExceptionHandler 实现全局异常处理

在这里插入图片描述

用于在特定的处理器类、方法中处理异常的注解

在这里插入图片描述

接收Throwable类作为参数,我们知道Throwable是所有异常的父类,所以说,可以自行指定所有异常

比如在方法上加:@ExceptionHandler(IllegalArgumentException.class),则表明此方法处理

IllegalArgumentException 类型的异常,如果参数为空,将默认为方法参数列表中列出的任何异常(方法抛出什么异常都接得住)。

下面的例子:处理所有IllegalArgumentException异常,域中加入错误信息errorMessage 并返回错误页面error

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(IllegalArgumentException.class)
    public ModelAndView handleException(IllegalArgumentException e){
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("errorMessage", "参数不符合规范!");
        return modelAndView;
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.预设全局数据

@ControllerAdvice 配合 @ModelAttribute 预设全局数据

我们先来看看 ModelAttribute注解类的源码

/**
 * Annotation that binds a method parameter or method return value
 * to a named model attribute, exposed to a web view. Supported
 * for controller classes with {@link RequestMapping @RequestMapping}
 * methods.
 * 此注解用于绑定一个方法参数或者返回值到一个被命名的model属性中,暴露给web视图。支持在
 * 在Controller类中注有@RequestMapping的方法使用(这里有点拗口,不过结合下面的使用介绍
 * 你就会明白的)
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {
<span class="token annotation punctuation">@AliasFor</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span>
String <span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">default</span> <span class="token string">""</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@AliasFor</span><span class="token punctuation">(</span><span class="token string">"value"</span><span class="token punctuation">)</span>
String <span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">default</span> <span class="token string">""</span><span class="token punctuation">;</span>

<span class="token keyword">boolean</span> <span class="token function">binding</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">default</span> <span class="token boolean">true</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

实际上这个注解的作用就是,允许你往 Model 中注入全局属性(可以供所有Controller中注有@Request Mapping的方法使用),valuename 用于指定 属性的 keybinding 表示是否绑定,默认为 true

具体使用方法如下:

  • 全局参数绑定

    • 方式一:
    @ControllerAdvice
    public class MyGlobalHandler {
        @ModelAttribute
        public void presetParam(Model model){
            model.addAttribute("globalAttr","this is a global attribute");
        }
    }
    
       
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这种方式比较灵活,需要什么自己加就行了,加多少属性自己控制

    • 方式二:
    @ControllerAdvice
    public class MyGlobalHandler {
    
    <span class="token annotation punctuation">@ModelAttribute</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> Map<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> String<span class="token punctuation">&gt;</span></span> <span class="token function">presetParam</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
        Map<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> String<span class="token punctuation">&gt;</span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> String<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"key1"</span><span class="token punctuation">,</span> <span class="token string">"value1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"key2"</span><span class="token punctuation">,</span> <span class="token string">"value2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"key3"</span><span class="token punctuation">,</span> <span class="token string">"value3"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> map<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这种方式对于加单个属性比较方便。默认会把返回值(如上面的map)作为属性的value,而对于key有两种指定方式:

  1. @ModelAttribute() 不传任何参数的时候,默认会把返回值的字符串值作为key,如上例的 key 则是 ”map"(值得注意的是,不支持字符串的返回值作为key)。
  2. @ModelAttribute("myMap") 传参数的时候,则以参数值作为key,这里 key 则是 ”myMap“。
  • 全局参数使用

    @RestController
    public class AdviceController {
    
    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"methodOne"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> String <span class="token function">methodOne</span><span class="token punctuation">(</span>Model model<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> 
        Map<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> Object<span class="token punctuation">&gt;</span></span> modelMap <span class="token operator">=</span> model<span class="token punctuation">.</span><span class="token function">asMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token punctuation">(</span>String<span class="token punctuation">)</span>modelMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"globalAttr"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    
    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"methodTwo"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> String <span class="token function">methodTwo</span><span class="token punctuation">(</span><span class="token annotation punctuation">@ModelAttribute</span><span class="token punctuation">(</span><span class="token string">"globalAttr"</span><span class="token punctuation">)</span> String globalAttr<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
        <span class="token keyword">return</span> globalAttr<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    
    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"methodThree"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> String <span class="token function">methodThree</span><span class="token punctuation">(</span>ModelMap modelMap<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">return</span> <span class="token punctuation">(</span>String<span class="token punctuation">)</span> modelMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"globalAttr"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
  • }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    这三种方式大同小异,其实都是都是从Model 中存储属性的 Map里取数据。

    3.请求参数预处理

    @ControllerAdvice 配合 @InitBinder 实现对请求参数的预处理

    再次之前我们先来了解一下 @IniiBinder,先看一下源码,我会提取一些重要的注释进行浅析

    /**
     * Annotation that identifies methods which initialize the
     * {@link org.springframework.web.bind.WebDataBinder} which
     * will be used for populating command and form object arguments
     * of annotated handler methods.
     * 粗略翻译:此注解用于标记那些 (初始化[用于组装命令和表单对象参数的]WebDataBinder)的方法。
     * 原谅我的英语水平,翻译起来太拗口了,从句太多就用‘()、[]’分割一下便于阅读
     *
     * Init-binder methods must not have a return value; they are usually
     * declared as {@code void}.
     * 粗略翻译:初始化绑定的方法禁止有返回值,他们通常声明为 'void'
     *
     * <p>Typical arguments are {@link org.springframework.web.bind.WebDataBinder}
     * in combination with {@link org.springframework.web.context.request.WebRequest}
     * or {@link java.util.Locale}, allowing to register context-specific editors.
     * 粗略翻译:典型的参数是`WebDataBinder`,结合`WebRequest`或`Locale`使用,允许注册特定于上下文的编辑 
     * 器。
     * 
     * 总结如下:
     *  1. @InitBinder 标识的方法的参数通常是 WebDataBinder。
     *  2. @InitBinder 标识的方法,可以对 WebDataBinder 进行初始化。WebDataBinder 是 DataBinder 的一
     * 		           个子类,用于完成由表单字段到 JavaBean 属性的绑定。
     *  3. @InitBinder 标识的方法不能有返回值,必须声明为void。
     */
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface InitBinder {
    	/**
    	 * The names of command/form attributes and/or request parameters
    	 * that this init-binder method is supposed to apply to.
    	 * <p>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.
    	 * 粗略翻译:此init-binder方法应该应用于的命令/表单属性和/或请求参数的名称。默认是应用于所有命	   		* 令/表单属性和所有由带注释的处理类处理的请求参数。这里指定模型属性名或请求参数名将init-binder		 * 方法限制为那些特定的属性/参数,不同的init-binder方法通常应用于不同的属性或参数组。
    	 * 我至己都理解不太理解这说的是啥呀,我们还是看例子吧
    	 */
    	String[] value() default {};
    }
    
     
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    我们来看看具体用途,其实这些用途在 Controller里也可以定义,但是作用范围就只限当前Controller,因此下面的例子我们将结合 ControllerAdvice 作全局处理。

    • 参数处理

      @ControllerAdvice
      public class MyGlobalHandler {
      
      <span class="token annotation punctuation">@InitBinder</span>
      <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">processParam</span><span class="token punctuation">(</span>WebDataBinder dataBinder<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
      
          <span class="token comment">/*
           * 创建一个字符串微调编辑器
           * 参数{boolean emptyAsNull}: 是否把空字符串("")视为 null
           */</span>
          StringTrimmerEditor trimmerEditor <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">StringTrimmerEditor</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      
          <span class="token comment">/*
           * 注册自定义编辑器
           * 接受两个参数{Class&lt;?&gt; requiredType, PropertyEditor propertyEditor}
           * requiredType:所需处理的类型
           * propertyEditor:属性编辑器,StringTrimmerEditor就是 propertyEditor的一个子类
           */</span>
          dataBinder<span class="token punctuation">.</span><span class="token function">registerCustomEditor</span><span class="token punctuation">(</span>String<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> trimmerEditor<span class="token punctuation">)</span><span class="token punctuation">;</span>
          
          <span class="token comment">//同上,这里就不再一步一步讲解了</span>
          binder<span class="token punctuation">.</span><span class="token function">registerCustomEditor</span><span class="token punctuation">(</span>Date<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span>
                  <span class="token keyword">new</span> <span class="token class-name">CustomDateEditor</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">SimpleDateFormat</span><span class="token punctuation">(</span><span class="token string">"yyyy-MM-dd"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      

    }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    这样之后呢,就可以实现全局的实现对 ControllerRequestMapping标识的方法中的所有 StringDate类型的参数都会被作相应的处理。

    Controller:

    @RestController
    public class BinderTestController {
    
    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"processParam"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> Map<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> Object<span class="token punctuation">&gt;</span></span> <span class="token function">test</span><span class="token punctuation">(</span>String str<span class="token punctuation">,</span> Date date<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{<!-- --></span>
        Map<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> Object<span class="token punctuation">&gt;</span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">,</span> Object<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"str"</span><span class="token punctuation">,</span> str<span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"data"</span><span class="token punctuation">,</span> date<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span>  map<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    

    }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    测试结果:

    在这里插入图片描述
    我们可以看出,strdate 这两个参数在进入 Controller 的test的方法之前已经被处理了,str 被去掉了两边的空格(%20 在Http url 中是空格的意思),String类型的 1997-1-10被转换成了Date类型。

    • 参数绑定

      参数绑定可以解决特定问题,那么我们先来看看我们面临的问题

      class Person {
      
      <span class="token keyword">private</span> String name<span class="token punctuation">;</span>
      <span class="token keyword">private</span> Integer age<span class="token punctuation">;</span>
      <span class="token comment">// omitted getters and setters.</span>
      

    }

    class Book {

    <span class="token keyword">private</span> String name<span class="token punctuation">;</span>
    <span class="token keyword">private</span> Double price<span class="token punctuation">;</span>
    <span class="token comment">// omitted getters and setters.</span>
    

    }

    @RestController
    public class BinderTestController {

    <span class="token annotation punctuation">@PostMapping</span><span class="token punctuation">(</span><span class="token string">"bindParam"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span>Person person<span class="token punctuation">,</span> Book book<span class="token punctuation">)</span> <span class="token keyword">throws</span> Exception <span class="token punctuation">{<!-- --></span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span>
        System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>book<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    

    }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    我们会发现 Person类和 Book 类都有 name属性,那么这个时候就会出先问题,它可没有那么只能区分哪个name是哪个类的。因此 @InitBinder就派上用场了:

    @ControllerAdvice
    public class MyGlobalHandler {
    
    <span class="token comment">/*
     * @InitBinder("person") 对应找到@RequstMapping标识的方法参数中
     * 找参数名为person的参数。
     * 在进行参数绑定的时候,以‘p.’开头的都绑定到名为person的参数中。
     */</span>
    <span class="token annotation punctuation">@InitBinder</span><span class="token punctuation">(</span><span class="token string">"person"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">BindPerson</span><span class="token punctuation">(</span>WebDataBinder dataBinder<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
        dataBinder<span class="token punctuation">.</span><span class="token function">setFieldDefaultPrefix</span><span class="token punctuation">(</span><span class="token string">"p."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token annotation punctuation">@InitBinder</span><span class="token punctuation">(</span><span class="token string">"book"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">BindBook</span><span class="token punctuation">(</span>WebDataBinder dataBinder<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
        dataBinder<span class="token punctuation">.</span><span class="token function">setFieldDefaultPrefix</span><span class="token punctuation">(</span><span class="token string">"b."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    

    }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    因此,传入的同名信息就能对应绑定到相应的实体类中:

    p.name -> Person.name b.name -> Book.name

    还有一点注意的是如果 @InitBinder("value") 中的 value 值和 Controller@RequestMapping() 标识的方法的参数名不匹配,则就会产生绑定失败的后果,如:

    @InitBinder(“p”)、@InitBinder(“b”)

    public void test(Person person, Book book)

    上述情况就会出现绑定失败,有两种解决办法

    第一中:统一名称,要么全叫p,要么全叫person,只要相同就行。

    第二种:方法参数加 @ModelAttribute,有点类似@RequestParam

    @InitBinder(“p”)、@InitBinder(“b”)

    public void test(@ModelAttribute(“p”) Person person, @ModelAttribute(“b”) Book book)

    如果有不足之处,欢迎在评论区评论。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值