Java后台防止客户端重复请求,提交表单实现原理

  

这篇文章主要介绍了Java后台防止客户端重复请求,提交表单实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  

<强>前言
  

  

在网络/应用程序项目中,有一些请求或操作会对数据产生影响(比如新增、删除,修改),针对这类请求一般都需要做一些保护,以防止用户有意或无意的重复发起这样的请求导致的数据错乱。

  

<强>常见处理方案
  

  

1。客户端

  

例如表单提交后将提交按钮设为禁用等等方法…

  

2。服务端

  

前端的限制仅能解决少部分问题,且不够彻底,后端自有的防重复处理措施必不可少,义不容辞。

  

在此提供一个我在项目中用到的方案。简单来说就是判断请求url和数据是否和上一次相同。

  

<强>方法步骤
  

  

1。主要逻辑:

  

给所有的url加一个拦截器,每次请求将url存入会话,下次请求验证url数据是否相同,相同则拒绝访问。

  

当然,我在此基础上做了一些优化,比如:

  

使用会话有局限性,用户量大了以后服务器会撑不住,在此我使用了复述来替换。

  

加入了令牌令牌机制。

  

2。实现步骤:

  

2.1自定义一个注解
  

     /* *   * @Title: SameUrlData   * @Description:自定义注解防止表单重复提交   * @Auther: xhq   * @Version: 1.0   * @create 2019/3/26十43   */@Inherited   @Target (ElementType.METHOD)   @Retention (RetentionPolicy.RUNTIME)   @Documented   公共@ interface SameUrlData {      }      

2.2自定义拦截器类

  
      <李>检查此接口调用的方法是否使用了SameUrlData注解,若没有使用,表示此接口不需要校验;李   <李>若使用了注解,获取请求url +参数,并去除一直在变化的参数(比如时间戳时间戳和签名标志)   <李>检查参数中是否有令牌参数(令牌代表不同的用户的唯一标识),没有直接放行   <李>有令牌参数,将牌+ url作为复述的关键,url +参数作为价值存入复述,并设定自动销毁时间李   <李>再次访问进行验证是否重复请求李   
        进口com.alibaba.fastjson.JSONObject;   进口com.tuohang.hydra.framework.common.spring.SpringKit;   进口com.tuohang.hydra.toolkit.basis.string.StringKit;   进口org.slf4j.Logger;   进口org.slf4j.LoggerFactory;   进口org.springframework.data.redis.core.StringRedisTemplate;   进口org.springframework.stereotype.Component;   进口org.springframework.web.method.HandlerMethod;   进口org.springframework.web.servlet.handler.HandlerInterceptorAdapter;      进口javax.servlet.http.HttpServletRequest;   进口javax.servlet.http.HttpServletResponse;   进口java.lang.reflect.Method;   进口java.util.HashMap;   进口java.util.Iterator;   进口java.util.Map;   进口java.util.concurrent.TimeUnit;/* *   * @Title:防止用户重复提交数据拦截器   * @Description:将用户访问的url和参数结合牌存入复述,每次访问进行验证是否重复请求接口   * @Auther: xhq   * @Version: 1.0   * @create 2019/3/26大礼堂开幕   */@ component   公开课SameUrlDataInterceptor延伸HandlerInterceptorAdapter {      私有静态日志记录器=LoggerFactory.getLogger (SameUrlDataInterceptor.class);/* *   *是否阻止提交,意见阻止,真正放行   * @return   */@Override   公共布尔preHandle (HttpServletRequest请求,HttpServletResponse响应对象处理程序){抛出异常   如果处理程序instanceof HandlerMethod) {   HandlerMethod HandlerMethod=(HandlerMethod)处理程序;   方法方法=handlerMethod.getMethod ();   SameUrlData注释=method.getAnnotation (SameUrlData.class);   如果(注释!=null) {   如果(repeatDataValidator(请求)){//请求数据相同   日志。警告(“请不要重复提交url:“+ request.getServletPath ());   JSONObject结果=new JSONObject ();   result.put (“statusCode”、“500”);   result.put(“信息”、“请勿重复请求”);   response.setCharacterEncoding (“utf - 8”);   application/json response.setContentType (“;charset=utf - 8”);   response.getWriter () .write (result.toString ());   .close response.getWriter () ();//拦截之后跳转页面//字符串formRequest=request.getRequestURI ();//请求。setAttribute (“myurl formRequest);//request.getRequestDispatcher (“/WebRoot/共同/错误/jsp/error_message.jsp”)。提出(请求、响应);   返回错误;   其他}{//如果不是重复相同数据   返回true;   }   }   返回true;   其他}{   超级回报。preHandle(请求、响应处理程序);   }   }/* *   *验证同一个url数据是否相同提交,相同返回现实   * @param httpServletRequest   * @return   */公共布尔repeatDataValidator (HttpServletRequest HttpServletRequest) {//获取请求参数地图   Map

Java后台防止客户端重复请求,提交表单实现原理