1.我们在配置拦截器时需实现接口HandlerInterceptor
package com.example.springbootdemo.common.conf.interceptor;
import com.example.springbootdemo.common.conf.exceptions.CustomException;
import com.example.springbootdemo.common.response.ResultCode;
import com.example.springbootdemo.common.utils.JwtTokenUtils;
import com.example.springbootdemo.common.utils.RedisUtil;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* @ClassName: CustomInterceptor
* @Description: 拦截器
* @Author: WangBin
* @Date: 2023/7/19 0:01
*/
public class CustomInterceptor implements HandlerInterceptor {
private static RedisUtil redisUtil;
@Autowired
public void init(RedisUtil redisUtil) {
CustomInterceptor.redisUtil = redisUtil;
}
// redisUtil这个如果直接按下面这种方式注入的话是没有办法注入的,只能通过上面这种写法注入
// @Autowired
// private RedisUtil redisUtil;
/**
* 拦截所有请求,验证TOKEN是否有效
*
* @param request
* @param response
* @param handler
* @return
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 获取请求头中的token
String token = request.getHeader("token");
// 判断token是否存在或为空
if(StringUtils.isNullOrEmpty(token)) {
throw new CustomException(ResultCode.TOKEN_IS_NULL);
}
// 验证token是否有效
Map<String, Object> map = JwtTokenUtils.analysisToken(token);
if(map == null) {
throw new CustomException(ResultCode.TOKEN_ERROR);
}
// 从redis中读取用户信息(后续需要)
Map<Object, Object> userInfo = redisUtil.hmget(token);
System.out.println(userInfo);
if(userInfo == null || userInfo.isEmpty()) {
// token失效
throw new CustomException(ResultCode.TOKEN_INVALID);
}
return true;
}
}
2. 拦截器会获取请求头中的Token(令牌),然后检查请求头中的Token是否存在,如果Token存在,将会调用JwtTokenUtils工具类中的analysisToken()方法验证Token是否有效,如果Token有效将会调用redisUtil工具类的hmget()方法验证请求头中Token在Redis中是否过期。
3.配置过滤器并实现WebMvcConfigurer接口
package com.example.springbootdemo.common.conf.interceptor;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: WebAppConfig
* @Description: 过滤器
* @Author: WangBin
* @Date: 2023/7/18 23:59
*/
public class WebAppConfig implements WebMvcConfigurer {
// 配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 创建一个字符串数组,里面放入需要过滤掉的路径
List<String> urls = new ArrayList<>();
urls.add("/favicon.ico");
urls.add("/error");
urls.add("/swagger-resources/**");
urls.add("/webjars/**");
urls.add("/v2/**");
urls.add("/doc.html");
urls.add("**/swagger-ui.html");
urls.add("/swagger-ui.html/**");
registry.addInterceptor(new CustomInterceptor())
.addPathPatterns("/**") // 该方法是配置需要拦截的路径
.excludePathPatterns("/user/login/**")
.excludePathPatterns(urls); // 该方法是配置不要拦截的路径
}
// 资源映射增加
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
WebMvcConfigurer.super.addResourceHandlers(registry);
}
// 解决跨域问题
// <-cors
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedOriginPatterns("*")
.allowedHeaders("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}
// cors->
}
4.我们在addInterceptors方法中去配置拦截器
- InterceptorRegistry中的addInterceptor()方法是用来添加拦截器的
- InterceptorRegistry中的addPathPatterns方法是用来添加需要拦截的路径的
- InterceptorRegistry中的excludePathPatterns()方法是用来添加放行(过滤)的路径的
5.我们的拦截器和过滤器就配置完成了!