拦截器是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。
作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。
快速入门:
1.定义拦截器,实现HandlerInterceptor接口,并重写所有方法。
2.注册拦截器。
代码
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override //目标资源方法运行前执行,返回true:放行 返回false:不放行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle ...");
return true;
}
@Override //目标资源方法运行后执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("psetHandle ...");
}
@Override //视图渲染完毕后运行,最后运行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("anterCompletion ...");
}
}
注意:在filter中拦截所有路径是("/*"),而在拦截器中拦截所有路径是("/**")
@Configuration //配置类
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginCheckInterceptor loginCheckInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
}
}
使用细节:
①:拦截器可以根据需求,配置不同的拦截路径。
public void addInterceptors(InterceptorRegistry registry) { //addPathPatterns拦截那些资源
registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
//excludePathPatterns 不需要拦截那些资源
}
②:执行流程
@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override //目标资源方法运行前执行,返回true:放行 返回false:不放行
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
//1获取请求url
String url = req.getRequestURI().toString();
log.info("请求的url:{}",url);
//2.判断请求url中是否包含login,如果有,说明是登陆操作,放行
if (url.contains("login")){
log.info("登陆操作,放行");
return true;
}
//3.获取请求头中的令牌(token)
String jwt = req.getHeader("token");
//4.判断令牌是否存在,如果不存在,返回错误数据 StringUtils.hasLength(jwt) 判断字符串是否有长度
if (!StringUtils.hasLength(jwt)){
log.info("请求头token为空,返回未登录信息");
Result error = Result.error("NOT_LOGIN");
//手动转换 将对象转换成json fastJSON工具包 pom引入依赖
String notLogin = JSONObject.toJSONString(error);
resp.getWriter().write(notLogin);
return false;
}
//5.解析token,如果解析失败返回错误结果
try {
JwtUtils.parseJWT(jwt);
} catch (Exception e) { //报错说明解析失败 校验不成功
e.printStackTrace();
log.info("校验失败,返回错误信息");
Result error = Result.error("NOT_LOGIN");
String notLogin = JSONObject.toJSONString(error);
resp.getWriter().write(notLogin);
return false;
}
//6.放行
log.info("令牌合法直接放行");
return true;
}
@Override //目标资源方法运行后执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("psetHandle ...");
}
@Override //视图渲染完毕后运行,最后运行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("anterCompletion ...");
}
}