抗ブラシを制限するインタフェース注釈を実装することにより、

注釈スタイルを使用します

1)コメントを定義します。

@Retention(RUNTIME)
@Target(METHOD)
パブリック@interfaceのAccessLimit {
     int型秒()。
    int型MAXCOUNT(); 
}

2)注釈このような従来の方法は、流量制限器を必要とする追加

@AccessLimit(秒= 5、MAXCOUNT = 5

3)インターセプタの判断において、この方法は、修飾AccessLimitコメントを使用するかどうかを確認し

@Component
 パブリック クラスAccessInterceptorはHandlerInterceptorAdapter {延び
    
    @Autowired 
    ; MiaoshaUserService miaoshaUserServiceを 
    
    @Autowired 
    RedisService redisService。
    
    @Override 
    公共preHandle(HttpServletRequestのリクエスト、HttpServletResponseの応答、オブジェクト・ハンドラ)ブール
            例外{スロー
        システム。アウト(.println " prehandle .... " );
        もし(ハンドラのinstanceof HandlerMethod){ 
            HandlerMethod HM = (HandlerMethod)ハンドラ。
            文字列methodNameの =hm.getMethod()のgetName();.
             IF(methodName.equals(" toLogin ")|| methodName.equals(" do_login " )){
                 リターン trueに; 
            } {
                 // スレッドコンテキストへのユーザーのログイン情報を取得する 
                MiaoshaUser =ユーザーのgetUser(要求、応答); 
                UserContext.setUser(ユーザ); 

                // 限定ブラシ抗分析注釈 
                accessLimit accessLimit = hm.getMethodAnnotation(accessLimit。クラス);
                 IF(accessLimit == NULL ){
                    返す ; 
                } 
                int型秒= accessLimit.seconds()。
                INT MAXCOUNT = accessLimit.maxCount()。
                文字列キー = request.getRequestURI()。
                ACCESSKEY AK = AccessKey.withExpire(秒)。
                整数カウント = redisService。取得(AK、キー、Integer型。クラス);
                もし(カウント== nullの){ 
                    redisService。セット(AK、キー、1 )。
                }  もし(カウント< MAXCOUNT){ 
                    redisService.incr(AK、キー)
                } { 
                    (応答、CodeMsg.ACCESS_LIMIT_REACHED)をレンダリングします。
                    リターン はfalse ; 
                } 
            } 
        } 
        戻り 
    } 
    
    プライベート ボイドがレンダリング(HttpServletResponseの応答、CodeMsg CM)は例外{スロー
        response.setContentType(" アプリケーション/ JSONを、文字セット= UTF-8 " )。
        OutputStream アウト = response.getOutputStream()。
        文字列str  = JSON.toJSONString(Result.error(CM))。
        アウト .WRITE(str.getBytes(" UTF-8 " ));
        アウト.flush();
        アウト.close(); 
    } 

    プライベートMiaoshaUserのgetUser(HttpServletRequestのリクエスト、HttpServletResponseの応答){ 
        文字列paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN)。
        ストリングcookieToken = getCookieValue(リクエスト、MiaoshaUserService.COOKI_NAME_TOKEN)。
        場合(StringUtils.isEmpty(cookieToken)&& StringUtils.isEmpty(paramToken)){
             スロー 新しいをGlobalException(CodeMsg.SESSION_ERROR)。
        } 
        文字列トークン = StringUtils.isEmpty(paramToken)?cookieToken:paramToken。
     //这里是从Redisの中取用户信息 MiaoshaUser miaoshaUser
= miaoshaUserService.getByToken(応答、トークン)。 もしヌル == miaoshaUser){ スロー 新しいGlobalException(CodeMsg.SESSION_ERROR)。 } 戻り miaoshaUserと、 } プライベートストリングgetCookieValue(HttpServletRequestの要求は、文字列cookiName){ クッキー[]クッキー = request.getCookies()。 もし(クッキー== NULL || cookies.length <= 0 ){ 戻り ヌル } のための(クッキークッキー:クッキー){ 場合(cookie.getName()に等しい(cookiName)){ 戻りcookie.getValueを(); } } 戻り ヌル } }
パブリック クラスUserContext { 
    
    プライベート 静的にThreadLocal <MiaoshaUser> userHolder = 新規のThreadLocal <MiaoshaUser> (); 
    
    パブリック 静的 ボイドSETUSER(MiaoshaUserユーザ){ 
        userHolder。セット(ユーザ)。
    } 
    
    パブリック 静的MiaoshaUserのgetUser(){
         戻り userHolder。取得(); 
    } 

}

 

アイデアがある:キーとして第1の上、ユーザIDとURLスプライシング後のユーザ要求は、1 Redisの値などの値に設定され、有効期限が設定されています。値は、アクセスの最大数を超えた場合、次回は、増分の使用を介してユーザの要求は、ユーザーがアクセスを拒否され、Redisの。

おすすめ

転載: www.cnblogs.com/moris5013/p/12350059.html