顾名思义,@ControllerAdvice
就是 @Controller
的增强版。@ControllerAdvice
主要用来处理全局数据, 一般搭配 @ExceptionHandler
、@ModelAttribute
以及 @InitBinder
使用。
处理全局异常
@ControllerAdvice
最常见的使用场景就是全局异常处理。例如用户上传的文件超过了限制大小,就会抛出异常,此时可以通过 @ControllerAdvice
结合 @ExceptionHandler
定义全局异常捕获机制,只需在系统中定义 CustomExceptionHandler 类(名字不限),然后添加 @ControllerAdvice
注解即可。也可以通过 assignableTypes
指定特定的 Controller
类,让异常处理类只处理特定类抛出的异常:
@ControllerAdvice(assignableTypes = {ExceptionController.class})
当系统启动时,该类就会被扫描到 Spring 容器中,然后定义 uploadException 方法(名字不限),在该方法上添加了 @ExceptionHandler
注解,其中定义的 MaxUploadSizeExceededException.class
表明该方法用来处理 MaxUploadSizeExceededException
类型的异常。如果想让该方法处理所有类型的异常,只需将 MaxUploadSizeExceededException
改为 Exception
即可 。方法的参数可以有异常实例、 HttpServletResponse
以 及 HttpServletRequest
、 Model
等 , 返回值可以是一段 JSON 、一 个ModelAndView
、 一个逻辑视图名等。代码如下:
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(MaxUploadSizeExceededException.class)
public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter printWriter = response.getWriter();
printWriter.write("上传文件大小超出限制!");
printWriter.flush();
printWriter.close();
}
}
注:
- 以上代码只会捕获
spring.servlet.multipart.max-file-size
,即单个文件超过规定值的情况,并不会捕获spring.servlet.multipart.max-request-size
多文件超出的情况,此时若超过则页面会无响应。 - 全局异常处理这种异常处理方式一般用来处理应用级别的异常,有一些容器级别的错误处理不了,例如从
Filter
中抛出异常,使用@ControllerAdvice
定义的全局异常处理机制就无法处理。
添加全局数据
@ControllerAdvice
是一个全局数据处理组件, 因此也可以在 @ControllerAdvice
中配置全局数据,使用 @ModelAttribute
注解进行配置,代码如下:
@ControllerAdvice
public class GlobalConfig {
@ModelAttribute(value = "info")
public Map<String, String> userInfo() {
HashMap<String, String> map = new HashMap<>();
map.put("username", "罗贯中");
map.put("gender", "男");
return map;
}
}
-
在全局配置中添加 userlnfo 方法,返回一个 map。该方法有一个注解
@ModelAttribute
,其中的value
属性表示这条返回数据的 key,而方法的返回值是返回数据的 value。 -
此时在任意请求的 Controller 中,通过方法参数中的
Model
都可以获取 info 的数据。@GetMapping("/config") @ResponseBody public void config(Model model) { Map<String, Object> map = model.asMap(); Set<String> keySet = map.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); Object value = map.get(key); System.out.println(key + "-->" + value); } }
请求参数预处理
@ControllerAdvice
结合 @InitBinder
还能实现请求参数预处理,即将表单中的数据绑定到实体类上时进行一些额外处理。
在 WebDataBinder
对象中,还可以设置允许的字段、禁止的字段、必填字段以及验证器等。
来源:CSDN
作者:siriusol
链接:https://blog.csdn.net/siriusol/article/details/104200960