HandlerInterceptor拦截器使用
1.在springboot中的使用
1.2自定义类实现HandlerInterceptor接口,重写三个方法
注意:只有perHandle方法返回true的时候,postHandle 和 afterCompletion 方法才会执行,如果业务不需要,就不用重写postHandle 和 afterCompletion 方法了
public class JWTInterceptor implements HandlerInterceptor {
// 重写preHandle方法,在请求发生前执行,此处对每个请求的token进行校验
// 但是登陆的时候没有token就不能对登陆的接口进行拦截,所以要设置自定义的拦截规则
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HashMap<String, Object> map = new HashMap<>();
String token = request.getHeader("token"); //从request中获取到请求头中的token,进行解析校验
try {
jwtUtil.verifyToken(token);//调用token解析的工具类进行解析
return true; //请求放行
} catch (SignatureVerificationException e) {
e.printStackTrace();
map.put("msg", "签名不一致异常");
} catch (TokenExpiredException e) {
e.printStackTrace();
map.put("msg", "令牌过期异常");
} catch (AlgorithmMismatchException e) {
e.printStackTrace();
map.put("msg", "算法不匹配异常");
} catch (InvalidClaimException e) {
e.printStackTrace();
map.put("msg", "失效的payload异常");
} catch (Exception e) {
e.printStackTrace();
map.put("msg", "token无效");
}
//map异常的数据要返回给客户端需要转换成json格式 @ResponseBody 内置了jackson
String resultJson = new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(resultJson);
return false; //异常不放行
}
// 当preHandle方法返回值为true的时候才会执行。
// 重写postHandle方法,在请求完成后执行。
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle执行了");
}
// 当preHandle方法返回值为true的时候才会执行。
// 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion执行了");
}
}
上边定义的将会在每个方法执行的时候都进行拦截,我们可以自定义拦截规格,拦截那些路径,不拦截哪些路径
1.2,自定义拦截规则
//配置拦截条件
@Configuration
public class interceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//参数为我们自定义类,实现了HandlerInterceptor接口重写了三个方法
registry.addInterceptor(new JWTInterceptor())
.addPathPatterns("/interceptorVerify/**") //拦截所有的路径
.excludePathPatterns("/login/**"); //放行login目录下的,因为生成token拦截就无法生成了
}
}
2.使用介绍
preHandle
调用时间:Controller方法处理之前
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行
若返回false,则中断执行,注意:不会进入afterCompletion
postHandle
调用前提:preHandle返回true
调用时间:Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序倒着执行。
备注:postHandle虽然post打头,但post、get方法都能处理
afterCompletion
调用前提:preHandle返回true
调用时间:DispatcherServlet进行视图的渲染之后
多用于清理资源
记录
8.1 拦截器介绍
Shiro使用了与Servlet一样的Filter接口进行扩展;所以如果对Filter不熟悉可以参考《Servlet3.1规范》http://www.iteye.com/blogs/subjects/Servlet-3-1了解Filter的工作原理。首先下图是Shiro拦截器的基础类图
原文链接:https://blog.csdn.net/qq_32347977/article/details/51083896
public class MyAdviceFilter extends AdviceFilter {
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
System.out.println("====预处理/前置处理");
return true;//返回false将中断后续拦截器链的执行
}
@Override
protected void postHandle(ServletRequest request, ServletResponse response) throws Exception {
System.out.println("====后处理/后置返回处理");
}
@Override
public void afterCompletion(ServletRequest request, ServletResponse response, Exception exception) throws Exception {
System.out.println("====完成处理/后置最终处理");
}
}