在实际项目中有时需要用到自定义注解方便业务的实现,比如说日志,在实现自定义注解时一般和拦截器一起结合,通过拦截器实现注解的业务,也可用aop实现,具体如下
先顶一个控制层,其中@VerifyToken就是我们要实现的自定义注解
@RestController
@RequestMapping("/user")
public class UserController {
/**
*@VerifyToken就是我们要实现的自定义注解
/
@VerifyToken // 加上注解表示需要该方法需要验证token
@GetMapping("/getUser")
public Result getUser(String id){
User u = userService.findUserById(id);
return new Result("1001","成功",u);
}
}
定义一个自定义注解接口类,还可以往注解类中添加其他属性
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface VerifyToken {
boolean required() default true;
}
编写拦截器,preHandle方法为主要方法
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
Map params = new HashMap<>();
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1) {
if (paramValues[0].length() != 0) {
params.put(paramName, paramValues[0]);
}
}
}
HandlerMethod hander = (HandlerMethod) handler;
System.out.println("请求类:"+hander.getClass()+";请求方法:"+((HandlerMethod) handler).getMethod().getName()+";请求参数:"+ JSONUtils.toJSonString(params));
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("222222222222222222222");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception{
boolean bo = false;
// 获取token
String token = request.getHeader("token");
// 如果不是映射到Controller直接放行
if(!(object instanceof HandlerMethod)){
bo = true;
}
// 检查是否需要验证token
HandlerMethod handlerMethod = (HandlerMethod)object;
Method method = handlerMethod.getMethod();
if(method.isAnnotationPresent(VerifyToken.class)){
String str = checkToken(method,token);
if(!StringUtils.isEmpty(str)) throw new RuntimeException(str);
else bo = true;
}else bo = true;
return bo;
}
public String checkToken(Method method,String token){
VerifyToken loginToken = method.getAnnotation(VerifyToken.class);
if(loginToken.required()){
if(null == token){
return "该请求没有token,请先获取token";
}
if(TokenUtil.verifyToken(token)){// 有效,判断是否要刷新令牌
return null;
}else{
return "无效令牌";
}
}
return null;
}
}
将拦截器注册到spring中管理,这样就完成了
@Component
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("=================请求已拦截");
// 拦截所有请求
registry.addInterceptor(authInterceptor).addPathPatterns("/**");
}
}



