一、概念
拦截器是Spring架构的一个概念,拦截器是在action请求到Controller之前所进行的操作。拦截器有三个方法,分别是在进入controller之前,return之前,return之后执行。
preHandle
调用时间:Controller方法处理之前
执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行
若返回false,则中断执行,注意:不会进入afterCompletion
postHandle
调用前提:preHandle返回true
调用时间:Controller方法处理完之后,DispatcherSerlet进行视图的渲染之前,也就是说在这个方法中可以对ModelAndView进行操作
备注:postHandle虽然post打头,但post、get方法都能处理
afterCompletion
调用前提:preHandle返回true
调用时间:DispatcherSerlet进行视图的渲染之后
备注:多用于清理资源
二、方法
(1)创建一个拦截器,实现HandlerInterceptor接口,重写此接口的三个方法,preHandle、postHandle、afteCompletion,只有第一个方法返回true时,才会进入Controller,否则不会处理Controller内容,也不会执行后面两个方法。
/**
* @author qingnianren
*/
public class InterceptorTest implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
(2)创建配置类InerceptorConfig,把创建好的拦截器InterceptorTest,注册到spring容器中,使用spring的注解@configuration。在项目启动时,spring会把拦截器配置到spring容器中。
/**
* @author qingnianren
* @Description: 拦截器配置类
*/
// 必须要有的注解,会在项目启动的时候自动注册拦截器
@Configuration
public class InerceptorConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链,addPathPatterns用于添加拦截规则,excludePathPatterns用于排除拦截
registry.addInterceptor(new InterceptorTest())
.addPathPatterns("/**")
.excludePathPatterns("/*", "/*");
super.addInterceptors(registry);
}
}
(3)创建一个controller,配置路径,进行测试
/**
* @author qingnianren
*/
@RestController
@RequestMapping("/")
public class TestController {
@PostMapping("/")
public String queryAll() {
return null;
}
}
三、Java实例
/**
* @author qingnianren
* @Description: 拦截器
*/
@Component
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {
@Autowired
private TokenService tokenService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 验证token是否已传
String strToken = request.getHeader("header中的TOKEN标识");
if (StrUtil.isBlank(strToken)) {
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
response.getWriter().print("please login");
return false;
}
// 验证token是否有效
String userToken = tokenService.getUserToken(strToken);
if (null == userToken) {
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
response.getWriter().print("please re-login");
return false;
}
//用户信息放入session,做缓存
ThreadLocalUtil.setSessionOpenId(userToken);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
ThreadLocalUtil.removeSessionOpenId();
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
/**
* @author qingnianren
* @Description: 拦截器配置类
*/
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
private TokenInterceptor tokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截需要登录的请求,排除需要拦截的请求
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns("/api/user/**", "/doc.html#/**");
super.addInterceptors(registry);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
}
}
青年人的责任重大,努力吧!