在写项目的过程中,如果使用filter的方式进行登录token验证,需要添加大量的过滤路径,每次添加新的接口后都要添加一次需要放行的接口,由此,使用拦截器+反射的机制拦截请求,判断是否需要放行
-
自定义注解,拦截Controller
方法
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FilterFrom {
//默认是拦截的,添加注解后放行
boolean value() default false;
}
-
实现HandlerInterceptor
接口 重写preHandle
方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//拦截获取添加在适配器上的注解,判断是否有添加的放行注解
HandlerMethod method = (HandlerMethod) handler;
FilterFrom filterFrom = method.getMethodAnnotation(FilterFrom.class);
/**
* 添加了filterfrom注解就进行登录验证
*
*
* 请求的方法可以有注解,也可以没有,有注解的情况下,进行判断值,如果是没注解的情况下呢,默认 拦截?
* 没注解就直接拦截,禁止请求。
* 解决办法:(自定义一个方法,返回boolean方法,获取token的方法。)
*/
//获取添加在方法上的注解,判断是否存在放行注解
if (filterFrom != null) {
//如果设置放行注解为true,就直接放行
if (filterFrom.value() == true) {
return true;
} else {
return doFilter(request, response);
}
}
//没添加注解,进行返回提示
return noDoFilter(request, response);
}
public static boolean doFilter(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=UTF-8");
//默认为false,拦截获取token
String token = null;
try {
token = request.getHeader(SystemConfig.TOKEN_HEADER);
} catch (NullPointerException e) {
e.printStackTrace();
}
if (StrUtil.checkNoEmpty(token)) {
//获取redis中token的key
String key = RedisKeyConfig.LOGIN_TOKEN + token;
//获取redis中token的key储存的value
String user = JedisUtil.getInstance().STRINGS.get(key);
if (user != null) {
//请求进来就刷新一次token的有效期
JedisUtil.getInstance().expire(key, RedisKeyConfig.LOGIN_TIME);
JedisUtil.getInstance().expire(RedisKeyConfig.LOGIN_USER +
new JSONObject(user).getInt("id"), RedisKeyConfig.LOGIN_TIME);
return true;
} else {
response.getWriter().print(new JSONObject(R.fail("登录有效期已过,请重新登陆")));
return false;
}
} else {
response.getWriter().print(new JSONObject(R.fail("您还没有登录,请登陆")));
return false;
}
}
public static boolean noDoFilter(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().print(new JSONObject(R.fail("您还没有登录,请登陆")));
return false;
}
-
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注解拦截器
registry.addInterceptor(new InterceptorUtil()).addPathPatterns("/**");
}
}