在寫項目的過程中,如果使用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("/**");
}
}