1. 程式人生 > 實用技巧 >使用自定義註解阻止短時間內的重複提交

使用自定義註解阻止短時間內的重複提交

思路: 1、自定義IdempotentAop註解。 2、把註解標註在controller層方法上。 3、進行前置增強業務的編寫。 詳細如下: 1、自定義IdempotentAop註解。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface IdempotentAop {
}
@Retention可以定義的值有三個 RetentionPolicy.SOURCE:註解只保留在原始檔,當Java檔案編譯成class檔案的時候,註解被遺棄 RetentionPolicy.CLASS:註解被保留到class檔案,但jvm載入class檔案時候被遺棄,這是預設的生命週期 RetentionPolicy.RUNTIME:註解不僅被儲存到class檔案中,jvm載入class檔案之後,仍然存在
@Target可以定義的值有十個 ElementType.TYPE:類、介面(包括註解型別)和列舉的宣告 ElementType.FIELD:欄位宣告(包括列舉常量) ElementType.METHOD:方法宣告 ElementType.PARAMETER:引數宣告 ElementType.CONSTRUCTOR:建構函式宣告 ElementType.LOCAL_VARIABLE:本地變數宣告 ElementType.ANNOTATION_TYPE:註解型別宣告 ElementType.PACKAGE:包宣告 ElementType.TYPE_PARAMETER:型別引數宣告,JavaSE8引進,可以應用於類的泛型宣告之處 ElementType.TYPE_USE:JavaSE8引進,此型別包括型別宣告和型別引數宣告,是為了方便設計者進行型別檢查 2、把註解標註在controller層方法上。
@IdempotentAop
@RequestMapping(value 
= "/updateChannelAdvertiser", produces = {"application/json"}, consumes = {"application/json"}, method = RequestMethod.POST) public ResponseEntity<String> updateChannelAdvertiser(HttpServletRequest request, @RequestBody String json) { }
3、進行前置增強業務的編寫。
@Aspect
@Component
@Slf4j
public class ControllerIdempotent { @Autowired private JedisManager jedisManager; private static final String PRE_REDIS_KEY="IDEMPOTENT:"; private static final int dbIndex=1; @Before("@annotation(com.xx.aop.IdempotentAop)") public void privilege(JoinPoint jp) { //方法 Signature signature = jp.getSignature(); //引數 Object[] args = jp.getArgs(); String s = MD5Utils.md5BySalt_OnlySecond(args[1].toString()); String currentKey=PRE_REDIS_KEY+signature.getName()+":"+s; Jedis jedis =null; try { jedis = jedisManager.getJedis(); jedis.select(dbIndex); String set = jedis.set(currentKey, "1", "NX", "EX", 30); if (set!=null){ jedisManager.saveValueByKey(dbIndex,currentKey,"1",30); }else { throw new OpenApiException("請勿重複提交 !"); } }finally { if (jedis!=null){ jedis.close(); } } } }
這裡@Before("@annotation(com.xx.aop.IdempotentAop)")的@Before代表著進行前置增強的,裡面的@annotation(com.xx.aop.IdempotentAop)代表進行基於註解的掃描。 具體實現就是把PRE_REDIS_KEY加上signature.getName()(方法名稱)+":"+s(請求json的md5加密字串)作為key進行redis的set,過期時間設定為30s。 如果set返回為null代表這個key裡面有值,即為重複提交,這是就會終止方法的執行,返回一個異常提示不要重複提交。