一.自定义拦截器
拦截器的实现分两步
1.创建自定义拦截器
2.将⾃定义拦截器加⼊ WebMvcConfigurer 的 addInterceptors ⽅法中。
1.自定义拦截器
实现⼀个⽤户登录的权限效验
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
HttpSession session = request.getSession(false);
if (session != null && session.getAttribute("userinfo") != null)
{
return true;
}
response.setStatus(401);
return false;
}
}
将⾃定义拦截器加⼊到系统配置
将上⼀步中的⾃定义拦截器加⼊到系统配置信息中,具体实现代码如下:
@Configuration
public class AppConfig implements WebMvcConfigurer {
// 添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 拦截所有接⼝
.excludePathPatterns("/art/param11"); // 排除接⼝
}
}
- addPathPatterns表示拦截接口
- excludePathPatterns表示不拦截的接口
排除所有的静态资源
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 拦截所有接⼝
.excludePathPatterns("/**/*.js")
.excludePathPatterns("/**/*.css")
.excludePathPatterns("/**/*.jpg")
.excludePathPatterns("/login.html")
.excludePathPatterns("/**/login"); // 排除接⼝
2.拦截器原理


Spring 中的拦截器也是通过动态代理和环绕通知的思想实现的
3.统一异常处理
统⼀异常处理使⽤的是 @ControllerAdvice + @ExceptionHandler 来实现的,@ControllerAdvice 表
示控制器通知类,@ExceptionHandler 是异常处理器,两个结合表示当出现异常的时候执⾏某个通知,
也就是执⾏某个⽅法事件,具体实现代码如下:
@ControllerAdvice
public class ErrorAdive {
@ExceptionHandler(Exception.class)
@ResponseBody
public Object handler(Exception e) {
HashMap<String, Object> map = new HashMap<>();
map.put("state", 0);
map.put("data", null);
map.put("msg", e.getMessage());
return map;
}
}
当有多个异常通知时,匹配顺序为当前类及其⼦类向上依次匹配
4.统一返回数据格式
使用统一返回数据格式好处有:
- 方便前后端交互,降低沟通成本
- 方便维护
统⼀的数据返回格式可以使⽤ @ControllerAdvice + ResponseBodyAdvice 的⽅式实现,具体实现代
码如下:
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
/**
* 内容是否需要重写(通过此⽅法可以选择性部分控制器和⽅法进⾏重写)
* 返回 true 表示重写
*/
@Override
public boolean supports(MethodParameter returnType, Class converterTyp
e) {
return true;
}
/**
* ⽅法返回之前调⽤此⽅法
*/
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType,Class selectedConverterType, ServerHttpRequest request,ServerHttpResponse response) {
if(body instanceof HashMap){
return body;
}
// 构造统⼀返回对象
HashMap<String, Object> result = new HashMap<>();
result.put("state", 1);
result.put("msg", "");
result.put("data", body);
return result;
}
}