@ControllerAdvice
- 描述
- 用法1-全局异常捕获
- 用法2-全局数据绑定
- 用法3-数据预处理
描述
@ControllerAdvice注解是Spring3.2中新增的注解,学名是Controller增强器,作用是给Controller控制器添加统一的操作或处理。
对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHandler用于全局异常的处理,但其作用不止于此。ControllerAdvice拆开来就是Controller Advice,关于Advice,在Spring的AOP中,是用来封装一个切面所有属性的,包括切入点和需要织入的切面逻辑。这里ControllerAdvice也可以这么理解,其抽象级别应该是用于对Controller进行切面环绕的,而具体的业务织入方式则是通过结合其他的注解来实现的。@ControllerAdvice是在类上声明的注解,其用法主要有三点:
1.结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的。
2.结合方法型注解@InitBinder,用于request中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的。
3.结合方法型注解@ModelAttribute,表示其注解的方法将会在目标Controller方法执行之前执行。
从上面的讲解可以看出,@ControllerAdvice的用法基本是将其声明在某个bean上,然后在该bean的方法上使用其他的注解来指定不同的织入逻辑。**不过这里@ControllerAdvice并不是使用AOP的方式来织入业务逻辑的,而是Spring内置对其各个逻辑的织入方式进行了内置支持**
用法1-全局异常捕获
结合@ExceptionHandler即可实现全局异常捕获,并处理,@ExceptionHandler可以传入要捕获的异常的Class<? extends Throwable>[]数组
package com.liurq.config.shiro.handle;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.NativeWebRequest;
@ControllerAdvice
public class UnauthorizedExceptionHandle {
/**
* 可以获取请求的request对象,按需进行操作
* 可以获取抛出的异常对象,按需进行操作
* 可对请求进行重定向,将请求重定向到某个页面或控制器
* 需要返回json串儿的话,在方法上添加@ResponseBody注解即可
* @param request
* @param e
* @return
*/
// @ResponseBody
@ExceptionHandler({UnauthorizedException.class})
public String unauthorizedException(NativeWebRequest request, UnauthorizedException e){
System.out.println(request.getParameter("param1"));
e.printStackTrace();
return "redirect:/403";
}
}
用法2-全局数据绑定
搭配@ModelAttribute注解可以做数据绑定,在到达控制器前,将属性放入modelMap中,可以通过name属性指定数据在map中的key,如果不指定的话,有相同返回类型会产生覆盖,建议每个都通过name参数指定key
package com.liurq.advice;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import java.util.HashMap;
import java.util.Map;
/**
* @Author:hyz
* @Date:2021-07-29
* @Desc:
**/
@ControllerAdvice
public class Advice2 {
/**
* 通过name参数指定返回值在modelMap中的key
* @return
*/
@ModelAttribute(name = "str1")
public String getData(){
return "i am str1";
}
/**
* 不指定key则为返回类型Map的首字母小写形式map
* @return
*/
@ModelAttribute
public Map<String,String> getData2(){
HashMap<String, String> map = new HashMap<>();
map.put("str2","i am str2");
return map;
}
/**
* 不指定key则为返回类型Map的首字母小写形式hashMap
* @return
*/
@ModelAttribute
public HashMap<String,String> getData3(){
HashMap<String, String> map = new HashMap<>();
map.put("str3","i am str3");
return map;
}
/**
* 在不指定key的情况下,有两个返回类型相同的数据绑定,则会产生覆盖
* @return
*/
@ModelAttribute
public HashMap<String,String> getData4(){
HashMap<String, String> map = new HashMap<>();
map.put("str4","i am str4");
return map;
}
}