通过zuul的过滤器 filter实现
//app 幂等过滤 @SuppressWarnings("all") @Order(Ordered.HIGHEST_PRECEDENCE) @WebFilter(filterName = "ValidAppIdempotent", urlPatterns = { "/app/api/inbound/inboundEdit","/app/api/outbound/outboundEdit" ,"/app/api/inbound/inboundEdit_NonNote","/app/api/outbound/outboundEdit_NonNote"} ) public class ValidAppIdempotent extends OncePerRequestFilter { private static final Logger logger = LoggerFactory.getLogger(ValidToken.class); public final static String ERROR_REPEATSUBMIT = "Repeated submission"; @Value("${appSign}") private String appSign; @Autowired protected StringRedisTemplate idempotentTemplate; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //获取 body 中post过来的数据 String contentType = request.getContentType(); if (StringUtils.isNotBlank(contentType) && contentType.indexOf(MediaType.APPLICATION_JSON.toString()) >= 0) { request = new BodyReaderHttpServletRequestWrapper(request); } String data = null; try { data = NetUtil.getBodyString(request); } catch (Exception e) { e.printStackTrace(); } //获取 url 中的数据 String sign = request.getParameter("sign"); String signMD5 = MD5.getSign(data, appSign); if (Boolean.parseBoolean(idempotentTemplate.opsForValue().get(signMD5))) { throw new ErrorSignException(ERROR_REPEATSUBMIT); } else { idempotentTemplate.opsForValue().set(signMD5, "true", ComContants.IDEMPOTENT_EXTIME, TimeUnit.SECONDS); } filterChain.doFilter(request, response); } }
测试:
@RequestMapping(value = "inboundEdit", method = RequestMethod.POST) public ApiResult<String> inboundEdit(@RequestBody ApiRequest<String> request) { ApiResult<String> r = new ApiResult<String>(); return r; }