【Springbootの接面プログラミング】注記インタフェースブラシ防止を実現

6531 ワード

ソース:https://www.jianshu.com/p/697f1c5eaa3f?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq
本文は1種のきわめて簡潔で、柔軟な汎用インタフェースのブラシ防止の実現方式を紹介して、ブラシ防止の方法に@Prevent注釈を加えることでメールのブラシ防止を実現することができる.使用方法は大体以下の通りです.
/**
     *  
     *
     * @param request
     * @return
     */
    @ResponseBody
    @GetMapping(value = "/testPrevent")
    @Prevent // ( , 、 )
    public Response testPrevent(TestRequest request) {
        return Response.success(" ");
    }

目次

  • 1、ブラシカット面PreventAopを実現する.java
  • 2、使用ブラシ止め切面
  • 3、デモ
  • 1、ブラシカット面PreventAopを実現する.java


    大まかな論理は、すべての面を定義し、@Prevent注記を切り込み点とし、その切面の前置通知でその方法のすべての入参を取得し、そのBase 64を符号化し、入参Base 64符号化+完全な方法名をredisのkeyとし、入参をreidsのvalueとし、@Preventのvalueをredisのexpireとして、redisに格納する.この断面が入るたびに、参照Base 64符号化+完全メソッド名に基づいてredis値が存在するか否かを判断し、存在する場合は遮断ブラシ、存在しない場合は呼び出しを許可する.
    1.1注記Preventの定義
    package com.zetting.aop;
    
    import java.lang.annotation.*;
    
    /**
     *  
     *  :
     *  
     *  , 
     *
     * @author: zetting
     * @date:2018/12/29
     */
    @Documented
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Prevent {
    
        /**
         *  ( )
         *
         * @return
         */
        String value() default "60";
    
        /**
         *  
         */
        String message() default "";
    
        /**
         *  
         *
         * @return
         */
        PreventStrategy strategy() default PreventStrategy.DEFAULT;
    }
    

    1.2ブラシカット面を実現するPreventAop
    package com.zetting.aop;
    
    import com.alibaba.fastjson.JSON;
    import com.zetting.common.BusinessException;
    import com.zetting.util.RedisUtil;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    import java.lang.reflect.Method;
    import java.util.Base64;
    
    /**
     *  
     *
     * @author: zetting
     * @date: 2018/12/29 20:27
     */
    @Aspect
    @Component
    public class PreventAop {
        private static Logger log = LoggerFactory.getLogger(PreventAop.class);
    
        @Autowired
        private RedisUtil redisUtil;
    
    
        /**
         *  
         */
        @Pointcut("@annotation(com.zetting.aop.Prevent)")
        public void pointcut() {
        }
    
    
        /**
         *  
         *
         * @return
         */
        @Before("pointcut()")
        public void joinPoint(JoinPoint joinPoint) throws Exception {
            String requestStr = JSON.toJSONString(joinPoint.getArgs()[0]);
            if (StringUtils.isEmpty(requestStr) || requestStr.equalsIgnoreCase("{}")) {
                throw new BusinessException("[ ] ");
            }
    
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Method method = joinPoint.getTarget().getClass().getMethod(methodSignature.getName(),
                    methodSignature.getParameterTypes());
    
            Prevent preventAnnotation = method.getAnnotation(Prevent.class);
            String methodFullName = method.getDeclaringClass().getName() + method.getName();
    
            entrance(preventAnnotation, requestStr,methodFullName);
            return;
        }
    
    
        /**
         *  
         *
         * @param prevent
         * @param requestStr
         */
        private void entrance(Prevent prevent, String requestStr,String methodFullName) throws Exception {
            PreventStrategy strategy = prevent.strategy();
            switch (strategy) {
                case DEFAULT:
                    defaultHandle(requestStr, prevent,methodFullName);
                    break;
                default:
                    throw new BusinessException(" ");
            }
        }
    
    
        /**
         *  
         *
         * @param requestStr
         * @param prevent
         */
        private void defaultHandle(String requestStr, Prevent prevent,String methodFullName) throws Exception {
            String base64Str = toBase64String(requestStr);
            long expire = Long.parseLong(prevent.value());
    
            String resp = redisUtil.get(methodFullName+base64Str);
            if (StringUtils.isEmpty(resp)) {
                redisUtil.set(methodFullName+base64Str, requestStr, expire);
            } else {
                String message = !StringUtils.isEmpty(prevent.message()) ? prevent.message() :
                        expire + " ";
                throw new BusinessException(message);
            }
        }
    
    
        /**
         *  base64 
         *
         * @param obj  
         * @return base64 
         */
        private String toBase64String(String obj) throws Exception {
            if (StringUtils.isEmpty(obj)) {
                return null;
            }
            Base64.Encoder encoder = Base64.getEncoder();
            byte[] bytes = obj.getBytes("UTF-8");
            return encoder.encodeToString(bytes);
        }
    }
    

    注意:コアコード、その他のサブコード(redis構成、redisツールクラスなど)のみをダウンロードして参照できます.

    2、ブラシカットの使用


    MyControllerでのブラシの使用
    package com.zetting.modules.controller;
    
    import com.zetting.aop.Prevent;
    import com.zetting.common.Response;
    import com.zetting.modules.dto.TestRequest;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     *  
     */
    @RestController
    public class MyController {
    
        /**
         *  
         *
         * @param request
         * @return
         */
        @ResponseBody
        @GetMapping(value = "/testPrevent")
        @Prevent
        public Response testPrevent(TestRequest request) {
            return Response.success(" ");
        }
    
    
        /**
         *  
         *
         * @param request
         * @return
         */
        @ResponseBody
        @GetMapping(value = "/testPreventIncludeMessage")
        @Prevent(message = "10 ", value = "10")//value  10 10 
        public Response testPreventIncludeMessage(TestRequest request) {
            return Response.success(" ");
        }
    }
    
    

    3、プレゼンテーション


    GIF.gif
    giteeソース:https://gitee.com/Zetting/my-gather/tree/master/springboot-aop-prevent
    おすすめ:
  • 【Springbootの接面プログラミング】注釈敏感フィールド復号化
  • を実現
  • 【Springbootの検索ログの妙技】ログに一意のログIDを印刷する
  • 【Springbootの接面プログラミング】接面AOPによりインパラメトリックチェック
  • を実現
  • 【Springbootの接面プログラミング】カスタム注釈インプリメンテーションパラメータ指定列挙値チェック
  • 作者:zettingリンク:https://www.jianshu.com/p/697f1c5eaa3f出典:簡書簡書の著作権は著者の所有であり、いかなる形式の転載も著者に連絡して授権を得て出典を明記してください.