背景:
最近做的项目中使用了token验证用户登录状态,用户每次请求都需要验证token,出现重复代码,所以想着用拦截器+自定义注解来验证,将验证token 的代码放在自定义拦截器中,如果验证成功则返回 true 放行,如果验证失败则返回 false 程序运行终止,但是验证失败我是要返回给前端错误信息的,具体怎么实现直接看代码。
代码:
1. MyInterceptor 实现 HandlerInterceptor
@Component
public class MyInterceptor implements HandlerInterceptor {
@Autowired
private UserLoginDAO userLoginDAO;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
TokenAuthenticate annotation = ((HandlerMethod) handler).getMethodAnnotation(TokenAuthenticate.class);
// 没有添加注解
if (annotation == null){
return true;
}else {
// 添加了注解
// 取出token
String parameter = request.getParameter("json");
JSONObject jsonObject = JSONObject.parseObject(parameter);
Integer userId = Integer.valueOf(jsonObject.getString("userId"));
String token = jsonObject.getString("token");
UserLogin ul = new UserLogin();
ul.setUserId(userId);
UserLogin userLogin = userLoginDAO.selectOne(ul);
if (userLogin != null && userLogin.getToken().equals(token)){
return true;
}else {
printJson(response);
return false;
}
}
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
private static void printJson(HttpServletResponse response) {
String content = JSON.toJSONString(BaseApiService.setErrorResult("登录失效,请重新登录"));
printContent(response, content);
}
private static void printContent(HttpServletResponse response, String content) {
try {
response.reset();
response.setContentType("application/json");
response.setHeader("Cache-Control", "no-store");
response.setCharacterEncoding("UTF-8");
PrintWriter pw = response.getWriter();
pw.write(content);
pw.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. InterceptorConfig 继承 WebMvcConfigurerAdapter 这里主要是为了MyInterceptor中DAO的注入,如果MyInterceptor中没有注入DAO那么这个InterceptorConfig可以不要,因为有自定义注解。
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Bean
public HandlerInterceptor getMyInterceptor(){
return new MyInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptor = registry.addInterceptor(getMyInterceptor());
}
}
3. TokenAuthenticate 自定义注解
@Documented
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface TokenAuthenticate {
}