By implementing the interface annotation limiting anti brush

Using annotation style

1) Define a comment

@Retention(RUNTIME)
@Target(METHOD)
public @interface AccessLimit {
    int seconds();
    int maxCount();
}

2) add annotations such prior methods require a flow restrictor

@AccessLimit(seconds=5, maxCount=5)

3) In the judgment of interceptors, to see whether the method uses a modified AccessLimit comment

@Component
public class AccessInterceptor  extends HandlerInterceptorAdapter{
    
    @Autowired
    MiaoshaUserService miaoshaUserService;
    
    @Autowired
    RedisService redisService;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("prehandle....");
        if(handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod)handler;
            String methodName =hm.getMethod () getName ();.
             IF (methodName.equals ( " toLogin " ) || methodName.equals ( " do_login " )) {
                 return  to true ; 
            } the else {
                 // Get the user login information into the thread context 
                MiaoshaUser = User the getUser (Request, Response); 
                UserContext.setUser (User); 

                // Analyzing brush anti limiting annotation 
                AccessLimit accessLimit = hm.getMethodAnnotation (AccessLimit. class );
                 IF (accessLimit == null ) {
                    return true;
                }
                int seconds = accessLimit.seconds();
                int maxCount = accessLimit.maxCount();
                String key = request.getRequestURI();
                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)) {
            throw new GlobalException(CodeMsg.SESSION_ERROR);
        }
        String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
     //这里是从redis中取用户信息 MiaoshaUser miaoshaUser
= miaoshaUserService.getByToken(response, token); if(null == miaoshaUser){ throw new GlobalException(CodeMsg.SESSION_ERROR); } return miaoshaUser; } 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; } }
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();
    }

}

 

The idea is: a user request after the first over, the user id and url splicing as key, 1 is set to the value as redis values, and set an expiration time. Next time the user requests over the use of increment redis when the value exceeds the maximum number of accesses, the user is denied access.

Guess you like

Origin www.cnblogs.com/moris5013/p/12350059.html