springboot2.1+redis+拦截器防止表单重复提交详细介绍

    科技2022-08-08  107

    创建AutoIdempotent 拦截注解,后面使用在方法直接注解即可

    @Target(ElementType.METHOD) //应用在方法级别上 @Retention(RetentionPolicy.RUNTIME)//运行时 public @interface AutoIdempotent { }

    创建拦截器

    public class AutoIdempotentInterceptor implements HandlerInterceptor{ @Autowired private TokenServiceImpl tokenService; //token生成类 /** * 预处理 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!(handler instanceof HandlerMethod)) { return true; } 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){ response.setContentType("text/html;charset=UTF-8"); Map<String,Object> responseData = new HashMap<>(); Map<String,Object> map = new HashMap<>(); if(ex instanceof BusinessException){ BusinessException businessException = (BusinessException) ex;//自定义异常类 responseData.put("code",businessException.getCode()); responseData.put("msg",businessException.getMsg()); }else { responseData.put("code",EmCommonError.SYSTEM_EXCEPTION.getCode()); responseData.put("msg",EmCommonError.SYSTEM_EXCEPTION.getMsg()); } map.put("status","success"); map.put("data",responseData); writeReturnJson(response, JSON.toJSONString(map)); } } //必须返回true,否则会被拦截一切请求 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } /** * 返回的json值 * @param response * @param json * @throws Exception */ private void writeReturnJson(HttpServletResponse response, String json) throws Exception{ response.setContentType("text/html;charset=UTF-8"); PrintUtil printUtil = new PrintUtil(response); //统一print格式返回类处理返回前端json数据 printUtil.print(json); } }

    注册拦截器

    /** * 设置拦截路径 */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(exceptionInterceptor()).addPathPatterns("/**"); //其他异常的拦截器,此处不用管 registry.addInterceptor(autoIdempotentInterceptor()).addPathPatterns("/**"); } }

    controller处使用,需要防止重复提交表单的方法@AutoIdempotent 注解即可

    /* * @RequestBody ShopModel shopModel 接收前端post请求的参数, * @RequestHeader(name="token")接收前端request.header请求头的token * @AutoIdempotent //此处防重方法注解 */ @PostMapping("setShop") @AutoIdempotent @ResponseBody public CommonReturnType setShop(@RequestBody ShopModel shopModel,@RequestHeader(name = "token") String myHeader,HttpServletResponse response) throws BusinessException{ public class MyConstants { public static final String Constant_TOKEN_PREFIX_USER = "user:"; public static final String Constant_TOKEN_NAME = "token"; public static final String Constant_NO_TOKEN = "参数不合法"; public static final String Constant_REPETITIVE_OPERATION = "重复性操作"; } public interface EmBase { public int getCode(); public String getMsg(); public EmBase setMsg(String msg); } public enum EmUser implements EmBase { GET_TOKEN_SUCCESS(11001,"获取token成功"),//for-api ; private Integer code; private String msg; private EmUser(Integer code, String msg) { this.code = code; this.msg = msg; } @Override public int getCode() { return this.code; } @Override public String getMsg() { return this.msg; } @Override public EmBase setMsg(String msg) { this.msg = msg; return this; } } public enum EmUserError implements EmBase { NO_TOKEN_EXCEPTION(1009,"参数不合法"), REPETITIVE_OPERATION(1010,"重复提交了,请稍等"),; private Integer code; private String msg; private EmUserError(Integer code, String msg) { this.code = code; this.msg = msg; } @Override public int getCode() { return this.code; } @Override public String getMsg() { return this.msg; } @Override public EmBase setMsg(String msg) { this.msg = msg; return this; } }

    此外: token生成工具类 public class TokenService

    redis工具类 public class RedisUtil

    如果需要全部文件请到csdn下载。

    Processed: 0.013, SQL: 8