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

创建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下载。

你可能感兴趣的:(java,web,springboot,表单防重提交)