(1)什么是拦截器?
在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作,拦截是AOP的一种实现策略
(2)如何用拦截器:
第一步,实现HandlerInterceptor接口或者它的实现子类:HandlerInterceptorAdapter
第二步,实现接口中的方法:
preHandle:在业务处理器处理请求之前被调用 postHandle:在业务处理器处理请求执行完成后 afterCompletion:在完全处理完请求后被调用,可用于清理资源等
第三步,创建配置类,配置拦截器需要拦截的路径
(3)使用场景
1、微信授权登录,调用后端接口wxLogin,接口生成token,登录用户信息存入Redis,返回token
2、前端接收到微信登录接口返回的token
3、每次发送请求时候,把token放到请求头里面
4、后端从请求头获取token,从token中获取userId,根据userId获取登录的用户信息
(4)添加登录拦截器
public class UserLoginInterceptor implements HandlerInterceptor {
private RedisTemplate redisTemplate;
public UserLoginInterceptor(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
this.initUserLoginVo(request);
return true;
}
private void initUserLoginVo(HttpServletRequest request){
//从请求头获取token
String token = request.getHeader("token");
System.out.println(token);
if (!StringUtils.isEmpty(token)) {
Long userId = JwtHelper.getUserId(token);
UserLoginVo userLoginVo = (UserLoginVo)redisTemplate.opsForValue().get(RedisConst.USER_LOGIN_KEY_PREFIX + userId);
if(userLoginVo != null) {
//将UserInfo放入上下文中
AuthContextHolder.setUserId(userLoginVo.getUserId());
AuthContextHolder.setWareId(userLoginVo.getWareId());
}
}
}
}
(5)设置自定义拦截路径
@Configuration
public class LoginMvcConfigurerAdapter extends WebMvcConfigurationSupport {
@Resource
private RedisTemplate redisTemplate;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加自定义拦截器,设置路径
registry.addInterceptor(
new UserLoginInterceptor(redisTemplate))
.addPathPatterns("/api/**")
.excludePathPatterns("/api/user/weixin/wxLogin/*");
super.addInterceptors(registry);
}
}
注:addPathPatterns()方法为拦截的路径,excludePathPatterns()方法为放行的路径。