前言
在以前的文章中SpringBoot优雅的全局异常处理(二)——@RestControllerAdvice已经介绍过增强注解@ControllerAdvice,其实它的作用不止是来处理全局异常,还可以用来预设全局数据和预处理请求参数。下面来看看如何用@ControllerAdvice来进行请求参数预处理。
一、问题展示
-
新建两个实体类Book和Author
Book
package com.junya.areyouok.entity; import lombok.Data; /** * @author ZHANGCHAO * @date 2020/5/15 16:29 * @since 1.0.0 */ @Data public class Book { private String name; private Double price; }
Author
package com.junya.areyouok.entity; import lombok.Data; /** * @author ZHANGCHAO * @date 2020/5/15 16:30 * @since 1.0.0 */ @Data public class Author { private String name; private Integer age; }
两个实体有一个相同的属性:name
-
新建BookController类,写一个增加方法,接收Book和Author参数并打印出来
package com.junya.areyouok.controller; import com.junya.areyouok.entity.Author; import com.junya.areyouok.entity.Book; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; /** * @author ZHANGCHAO * @date 2020/5/15 16:31 * @since 1.0.0 */ @RestController public class BookController { @PostMapping("/addBook") public void addBook(Book book, Author author){ System.out.println(book); System.out.println(author); } }
-
打开postman,执行请求,如下:
这个时候,添加操作就会有问题,因为两个实体类都有一个 name 属性,从前端传递时 ,无法区分。此时,通过 @ControllerAdvice 的全局数据预处理可以解决这个问题。
二、解决问题之请求参数预处理
-
方法中变量取别名
package com.junya.areyouok.controller; import com.junya.areyouok.entity.Author; import com.junya.areyouok.entity.Book; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; /** * @program are-you-ok * @description: * @author: zhangchao * @date: 2020/05/16 16:24 * @since: 1.0.0 */ @RestController public class BookController { @PostMapping("/addBook") public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author) { System.out.println(book); System.out.println(author); } }
-
新建请求预处理类GlobalData,增加两个方法,分别处理a和b的前缀
package com.junya.areyouok; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.InitBinder; /** * @program are-you-ok * @description: * @author: zhangchao * @date: 2020/05/16 16:30 * @since: 1.0.0 */ @ControllerAdvice public class GlobalData { @InitBinder("a") public void initA(WebDataBinder binder){ binder.setFieldDefaultPrefix("a."); } @InitBinder("b") public void initB(WebDataBinder binder){ binder.setFieldDefaultPrefix("b."); } }
@InitBinder(“b”) 注解表示该方法用来处理和Book和相关的参数,在方法中,给参数添加一个 b 前缀,即请求参数要有b前缀。
注意,postman中请求参数前也要加前缀:
-
重启项目,再次发送请求
OK,接收参数已成功赋值到相应的实体类上了。