瞬间几千次的重复提交,我用SpringBoot+Redis扛住了
/*** redis工具类*/@ComponentpublicclassRedisService{@AutowiredprivateRedisTemplate redisTemplate;/*** 写入缓存* @param key* @param value* @return*/publicbooleanset(finalString key, Object value) {boolean result = false;try{ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);result = true;} catch(Exception e) {e.printStackTrace();}return result;}/*** 写入缓存设置时效时间* @param key* @param value* @return*/publicboolean setEx(finalString key, Object value, Long expireTime) {boolean result = false;try{ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();operations.set(key, value);redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);result = true;} catch(Exception e) {e.printStackTrace();}return result;}/*** 判断缓存中是否有对应的value* @param key* @return*/publicboolean exists(finalString key) {return redisTemplate.hasKey(key);}/*** 读取缓存* @param key* @return*/publicObjectget(finalString key) {Object result = null;ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();result = operations.get(key);return result;}/*** 删除对应的value* @param key*/publicboolean remove(finalString key) {if(exists(key)) {Booleandelete= redisTemplate.delete(key);returndelete;}returnfalse;}}
@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public@interfaceAutoIdempotent{}
publicinterfaceTokenService{/*** 创建token* @return*/public String createToken();/*** 检验token* @param request* @return*/publicboolean checkToken(HttpServletRequest request) throwsException;}
@ServicepublicclassTokenServiceImplimplementsTokenService{@AutowiredprivateRedisService redisService;/*** 创建token** @return*/@OverridepublicString createToken() {String str = RandomUtil.randomUUID();StrBuilder token = newStrBuilder();try{token.append(Constant.Redis.TOKEN_PREFIX).append(str);redisService.setEx(token.toString(), token.toString(),10000L);boolean notEmpty = StrUtil.isNotEmpty(token.toString());if(notEmpty) {return token.toString();}}catch(Exception ex){ex.printStackTrace();}returnnull;}/*** 检验token** @param request* @return*/@Overridepublicboolean checkToken(HttpServletRequest request) throwsException{String token = request.getHeader(Constant.TOKEN_NAME);if(StrUtil.isBlank(token)) {// header中不存在tokentoken = request.getParameter(Constant.TOKEN_NAME);if(StrUtil.isBlank(token)) {// parameter中也不存在tokenthrownewServiceException(Constant.ResponseCode.ILLEGAL_ARGUMENT, 100);}}if(!redisService.exists(token)) {thrownewServiceException(Constant.ResponseCode.REPETITIVE_OPERATION, 200);}boolean remove = redisService.remove(token);if(!remove) {thrownewServiceException(Constant.ResponseCode.REPETITIVE_OPERATION, 200);}returntrue;}}
@ConfigurationpublicclassWebConfigurationextendsWebMvcConfigurerAdapter{@ResourceprivateAutoIdempotentInterceptor autoIdempotentInterceptor;/*** 添加拦截器* @param registry*/@Overridepublicvoid addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(autoIdempotentInterceptor);super.addInterceptors(registry);}}
/*** 拦截器*/@ComponentpublicclassAutoIdempotentInterceptorimplementsHandlerInterceptor{@AutowiredprivateTokenService tokenService;/*** 预处理** @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throwsException{if(!(handler instanceofHandlerMethod)) {returntrue;}HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();//被ApiIdempotment标记的扫描AutoIdempotent methodAnnotation = method.getAnnotation(AutoIdempotent.class);if(methodAnnotation != null) {try{return tokenService.checkToken(request);// 幂等性校验, 校验通过则放行, 校验失败则抛出异常, 并通过统一异常处理返回友好提示}catch(Exception ex){ResultVo failedResult = ResultVo.getFailedResult(101, ex.getMessage());writeReturnJson(response, JSONUtil.toJsonStr(failedResult));throw ex;}}//必须返回true,否则会被拦截一切请求returntrue;}@Overridepublicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throwsException{}@Overridepublicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throwsException{}/*** 返回的json值* @param response* @param json* @throws Exception*/privatevoid writeReturnJson(HttpServletResponse response, String json) throwsException{PrintWriter writer = null;response.setCharacterEncoding("UTF-8");response.setContentType("text/html; charset=utf-8");try{writer = response.getWriter();writer.print(json);} catch(IOException e) {} finally{if(writer != null)writer.close();}}}
@RestControllerpublicclassBusinessController{@ResourceprivateTokenService tokenService;@ResourceprivateTestService testService;@PostMapping("/get/token")publicString getToken(){String token = tokenService.createToken();if(StrUtil.isNotEmpty(token)) {ResultVo resultVo = newResultVo();resultVo.setCode(Constant.code_success);resultVo.setMessage(Constant.SUCCESS);resultVo.setData(token);returnJSONUtil.toJsonStr(resultVo);}returnStrUtil.EMPTY;}@AutoIdempotent@PostMapping("/test/Idempotence")publicString testIdempotence() {String businessResult = testService.testIdempotence();if(StrUtil.isNotEmpty(businessResult)) {ResultVo successResult = ResultVo.getSuccessResult(businessResult);returnJSONUtil.toJsonStr(successResult);}returnStrUtil.EMPTY;}}
-END-
以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言。