自定義註解 本地緩存 防止重複提交

1.引入依賴guava

<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>21.0</version>
</dependency>

2.自定義註解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // 作用到方法上
@Retention(RetentionPolicy.RUNTIME) // 運行時有效
public @interface NoRepeatSubmit {

}

3.緩存

import java.util.concurrent.TimeUnit;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@Configuration
public class UrlCache {
	@Bean
    public Cache<String, Integer> getCache() {
		// 緩存有效期爲6秒
        return CacheBuilder.newBuilder().expireAfterWrite(6L, TimeUnit.SECONDS).build();
    }
}

4.定義AOP
注意:@Around非線程安全,需要synchronized 關鍵字

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.google.common.cache.Cache;
import com.xxx.xxx.util.Jackson2Util;
@Aspect
@Component
public class NoRepeatSubmitAop {
	private static final Logger logger= LogManager.getLogger(NoRepeatSubmitAop.class);
	
	@Autowired
    private Cache<String, Integer> cache;
	
    @Around("execution(* com.xxx.xxx..*Controller.*(..)) && @annotation(nrs)")
    public synchronized Object around(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) {
    	
    	try {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
            HttpServletRequest request = attributes.getRequest();
            String key = sessionId + "-" + request.getServletPath();
         // 如果緩存中有這個url視爲重複提交
            if (cache.getIfPresent(key) == null) {
                Object o = pjp.proceed();
                cache.put(key, 1);
                return o;
            } else {
                logger.info("重複提交");
                ModelAndView mv = new ModelAndView();
        		mv.setView(Jackson2Util.jsonView());
        		mv.addObject("code", 1);
        		mv.addObject("msg", "請不要重複提交!");
                return mv;
            }
        } catch (Throwable e) {
            e.printStackTrace();
            logger.error("驗證重複提交時出現未知異常!");
            ModelAndView mv = new ModelAndView();
    		mv.setView(Jackson2Util.jsonView());
    		mv.addObject("code", 2);
    		mv.addObject("msg", "驗證重複提交內部錯誤!");
            return mv;
        }
    }
}

4.Controller方法使用

@NoRepeatSubmit
	@RequestMapping("uploadData")
	public ModelAndView uploadData(UploadData data) throws Exception {
		ModelAndView mv = new ModelAndView();
		mv.setView(Jackson2Util.jsonView());
				mv.addObject("code","0");
				mv.addObject("msg","上傳成功");
				return mv;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章