4.4 @ControllerAdvice全局数据处理
- 1. 全局异常处理 @ExceptionHandler
- 2. 添加全局数据 @ModelAttribute
- 3. 请求参数预处理 @InitBinder
顾名思义,@ControllerAdvice 就是@Controller 增强版。@ControllerAdvice 主要用来处理全
局数据 ,一般搭配@ExceptionHandler、@ModelAttribute 及@InitBinder 使用。
1. 全局异常处理 @ExceptionHandler
2. 添加全局数据 @ModelAttribute
注解@ControllerAdvice是一个全局数据处理组件,因此也可以在@ControllerAdvice中配置全局数据,使用@ModelAttribute注解进行配置,代码如下:
package com.ruoyi.web.core.config;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import java.util.HashMap;
import java.util.Map;
/**
* 配置全局数据
*/
@ControllerAdvice
public class GlobalConfig {
@ModelAttribute(value = "info")
public Map<String, String> userInfo() {
HashMap<String, String> userMap = new HashMap<>();
userMap.put("userName", "与海");
userMap.put("gender", "男");
return userMap;
}
}
代码解释:
- 在全局配置中添加userInfo方法,返回一个map。该方法有一个注解@ModelAttribute,其中
的value属性表示这条返回数据的key,而方法的返回值是返回数据的value。 - 此时在任意请求的Controller中,通过方法参数中的Model都可以获取info的数据。
测试
package com.ruoyi.web.controller.test;
import com.ruoyi.common.core.domain.AjaxResult;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("/test")
public class Test1Controller {
@GetMapping("/hello")
public AjaxResult hello(Model model) {
Map<String, Object> map = model.asMap();
return AjaxResult.success(map);
}
}
3. 请求参数预处理 @InitBinder
注解@ControllerAdvice结合@InitBinder还能实现请求参数预处理,即将表单中的数据绑定到实体类上时进行一些额外处理。
例如有两个实体类Book和Author,代码如下:
@Data
public class Book {
private String name;
private String author;
}
@Data
public class Author {
private String name;
private int age;
}
在Controller上需要接收两个实体类的数据,Controller中的方法定义如下:
/**
* 测试@ControllerAdvice+@InitBinder实现请求参数预处理
* @param book
* @param author
* @return
*/
@GetMapping("/book")
public AjaxResult book(Book book,Author author) {
return AjaxResult.success(book.toString() + author.toString());
}
此时在参数传递时,两个实体类中的name属性会混淆,@ControllerAdvice结合@InitBinder 可以顺利解决该问题。
配置步骤如下。
首先给Controller中方法的参数添加@ModelAttribute注解,代码如下:
/**
* 测试@ControllerAdvice+@InitBinder实现请求参数预处理
* @param book
* @param author
* @return
*/
@GetMapping("/book")
public AjaxResult book(@ModelAttribute("b") Book book,@ModelAttribute("a") Author author) {
return AjaxResult.success(book.toString() + author.toString());
}
然后配置@ControllerAdvice,代码如下:
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
/**
* 全局配置
*/
@ControllerAdvice
public class GlobalConfig {
/**
* 请求参数预处理
*
* @param binder
*/
@InitBinder("b")
public void init(WebDataBinder binder) {
binder.setFieldDefaultPrefix("b.");
}
@InitBinder("a")
public void init2(WebDataBinder binder) {
binder.setFieldDefaultPrefix("a.");
}
}
代码解释:
- 在GlobalConfig类中创建两个方法,第一个@InitBinder(“b”)表示该方法是处理@ModelAttribute(“b”)对应的参数的,第二个@InitBinder(“a”)表示该方法是处理@ModelAttribute(“a”)对应的参数的。
- 在每个方法中给相应的Field设置一个前缀,然后在浏览器中请求http:/localhost:8080/book?b.name=三国演义&b.author=罗贯中&a.name=曹雪芹&a.age=48,即可成功地区分出name属性。
- 在WebDataBinder对象中,还可以设置允许的字段、禁止的字段、必填字段以及验证器等。