限制访问次数

@Service
public class AccessInterceptor  extends HandlerInterceptorAdapter{
   
   @Autowired
   MiaoshaUserService userService;
   
   @Autowired
   RedisService redisService;
   
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
         throws Exception {
      if(handler instanceof HandlerMethod) {
         MiaoshaUser user = getUser(request, response);
         UserContext.setUser(user);
         HandlerMethod hm = (HandlerMethod)handler;
         AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
         if(accessLimit == null) {
            return true;
         }
         int seconds = accessLimit.seconds();
         int maxCount = accessLimit.maxCount();
         boolean needLogin = accessLimit.needLogin();
         String key = request.getRequestURI();
         if(needLogin) {
            if(user == null) {
               render(response, CodeMsg.SESSION_ERROR);
               return false;
            }
            key += "_" + user.getId();
         }else {
            //do nothing
         }
         AccessKey ak = AccessKey.withExpire(seconds);
         Integer count = redisService.get(ak, key, Integer.class);
          if(count  == null) {
              redisService.set(ak, key, 1);
          }else if(count < maxCount) {
              redisService.incr(ak, key);
          }else {
             render(response, CodeMsg.ACCESS_LIMIT_REACHED);
             return false;
          }
      }
      return true;
   }
   
   private void render(HttpServletResponse response, CodeMsg cm)throws Exception {
      response.setContentType("application/json;charset=UTF-8");
      OutputStream out = response.getOutputStream();
      String str  = JSON.toJSONString(Result.error(cm));
      out.write(str.getBytes("UTF-8"));
      out.flush();
      out.close();
   }

   private MiaoshaUser getUser(HttpServletRequest request, HttpServletResponse response) {
      String paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN);
      String cookieToken = getCookieValue(request, MiaoshaUserService.COOKI_NAME_TOKEN);
      if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
         return null;
      }
      String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
      return userService.getByToken(response, token);
   }
   
   private String getCookieValue(HttpServletRequest request, String cookiName) {
      Cookie[]  cookies = request.getCookies();
      if(cookies == null || cookies.length <= 0){
         return null;
      }
      for(Cookie cookie : cookies) {
         if(cookie.getName().equals(cookiName)) {
            return cookie.getValue();
         }
      }
      return null;
   }
   
}
@Retention(RUNTIME)
@Target(METHOD)
public @interface AccessLimit {
   int seconds();
   int maxCount();
   boolean needLogin() default true;
}
public class UserContext {
  
   private static ThreadLocal<MiaoshaUser> userHolder = new ThreadLocal<MiaoshaUser>();
   
   public static void setUser(MiaoshaUser user) {
      userHolder.set(user);
   }
   
   public static MiaoshaUser getUser() {
      return userHolder.get();
   }

}
@Configuration
public class WebConfig  extends WebMvcConfigurerAdapter{
   
   @Autowired
   UserArgumentResolver userArgumentResolver;
   
   @Autowired
   AccessInterceptor accessInterceptor;
   
   @Override
   public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
      argumentResolvers.add(userArgumentResolver);
   }
   
   @Override
   public void addInterceptors(InterceptorRegistry registry) {
      registry.addInterceptor(accessInterceptor);
   }
   
}
@AccessLimit(seconds=5, maxCount=5, needLogin=true)
@RequestMapping(value="/path", method=RequestMethod.GET)
@ResponseBody
public Result<String> getMiaoshaPath(HttpServletRequest request, MiaoshaUser user,
      @RequestParam("goodsId")long goodsId,
      @RequestParam(value="verifyCode", defaultValue="0")int verifyCode
      ) {
   if(user == null) {
      return Result.error(CodeMsg.SESSION_ERROR);
   }
   boolean check = miaoshaService.checkVerifyCode(user, goodsId, verifyCode);
   if(!check) {
      return Result.error(CodeMsg.REQUEST_ILLEGAL);
   }
   String path  =miaoshaService.createMiaoshaPath(user, goodsId);
   return Result.success(path);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值