自定义注解+拦截器
Posted benniaoxianfei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义注解+拦截器相关的知识,希望对你有一定的参考价值。
应用场景:限制接口访问次数;登录限制。
1.控制层入口增加自定义注解进行限制:@AccessLimit(seconds=5, maxCount=5, needLogin=true)
//5秒内最多登陆五次
1 @AccessLimit(seconds=5, maxCount=5, needLogin=true) 2 @RequestMapping(value="/path", method=RequestMethod.GET) 3 @ResponseBody 4 public Result<String> getMiaoshaPath(HttpServletRequest request, MiaoshaUser user, 5 @RequestParam("goodsId")long goodsId, 6 @RequestParam(value="verifyCode", defaultValue="0")int verifyCode) { 7 8 if(user == null) { 9 return Result.error(CodeMsg.SESSION_ERROR); 10 } 11 12 boolean check = miaoshaService.checkVerifyCode(user, goodsId, verifyCode); 13 if(!check) { 14 return Result.error(CodeMsg.REQUEST_ILLEGAL); 15 } 16 String path = miaoshaService.createMiaoshaPath(user, goodsId); 17 return Result.success(path); 18 }
2.自定义注解AccessLimit()类及其参数
1 import java.lang.annotation.Retention; 2 import java.lang.annotation.Target; 3 4 import static java.lang.annotation.ElementType.METHOD; 5 import static java.lang.annotation.RetentionPolicy.RUNTIME; 6 7 /** 8 *自定义注解 9 */ 10 @Retention(RUNTIME) 11 @Target(METHOD) 12 public @interface AccessLimit { 13 14 int seconds(); 15 int maxCount(); 16 boolean needLogin() default true; 17 18 19 20 }
3.自定义拦截器类 + 重写方法preHandle(); //实现业务逻辑
class AccessInterceptor extends HandlerInterceptorAdapter;
1 /** 2 * SpringBoot实现拦截器 3 * HandlerInterceptorAdapter:拦截器基类 4 * @Date 2020-04-26 16:01 5 */ 6 @Service 7 public class AccessInterceptor extends HandlerInterceptorAdapter { 8 9 @Autowired 10 MiaoshaUserService miaoshaUserService; 11 12 @Autowired 13 RedisService redisService; 14 15 16 @Override 17 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 18 Object handler) throws Exception { 19 20 if(handler instanceof HandlerMethod){ 21 22 //1.根据参数获取用户信息 23 MiaoshaUser miaoshaUser = getUser(request,response); 24 25 //2.把用户保存在ThreadLocal里 26 //收到请求---响应完成:是同一个线程 27 UserContext.setMiaoshaUser(miaoshaUser); 28 29 //3.获取使用该注解的方法传入的参数 30 HandlerMethod handlerMethod = (HandlerMethod)handler; 31 AccessLimit accessLimit = handlerMethod.getMethodAnnotation(AccessLimit.class); 32 33 if(accessLimit == null){ 34 //没有访问限制 35 return true; 36 } 37 int seconds = accessLimit.seconds(); 38 int maxCount = accessLimit.maxCount(); 39 boolean needLogin = accessLimit.needLogin(); 40 41 String uri = request.getRequestURI(); 42 43 if(needLogin){ 44 if(null == miaoshaUser){ 45 //有访问限制,返回错误信息 46 render(response, CodeMsg.SESSION_ERROR); 47 return false; 48 }else{ 49 uri = uri + "_" + miaoshaUser.getId(); 50 } 51 }else{ 52 //do nothing 53 } 54 55 //《重构-改善既有代码的设计》martine flower 56 //校验访问次数是否超过限制 57 AccessKey accessKey = AccessKey.withExpire(seconds); 58 Integer count = redisService.getRedis(accessKey, uri, Integer.class); 59 if(null == count) { 60 redisService.setRedis(accessKey, uri, 1); 61 }else if(count < maxCount) { 62 redisService.incr(accessKey, uri); 63 }else { 64 render(response, CodeMsg.ACCESS_LIMIT_REACHED); 65 //达到访问限制,返回错误信息 66 return false; 67 } 68 } 69 return true; 70 }
4.注册拦截器
重写方法addInterceptors(InterceptorRegistry registry);
1 /** 2 * @Date 2020-04-09 10:49 3 */ 4 @Configuration 5 public class WebConfig extends WebMvcConfigurerAdapter { 6 7 @Autowired 8 UserArgumentResolver userArgumentResolver; 9 10 @Autowired 11 AccessInterceptor accessInterceptor; 12 13 @Override 14 public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { 15 argumentResolvers.add(userArgumentResolver); 16 } 17 18 /** 19 * 注册拦截器 20 * @param registry 21 */ 22 @Override 23 public void addInterceptors(InterceptorRegistry registry) { 24 //registry.addInterceptor(accessInterceptor); 25 } 26 }
以上是关于自定义注解+拦截器的主要内容,如果未能解决你的问题,请参考以下文章
SSH开发 | 配合自定义注解 和 Stratus拦截器,实现 方法级粒度 用户鉴权