你的位置:首页 > ASP.net教程

[ASP.net教程]Spring MVC拦截器+注解方式实现防止表单重复提交


原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过。

注,如果是集群的方式,则需要将token放入到缓存中即可。

注解Token代码: 

1.@Target(ElementType.METHOD) 2.@Retention (RetentionPolicy.RUNTIME) 3.public @interface Token { 4.  5.   boolean needSaveToken () default false ; 6.  7.   boolean needRemoveToken () default false ; 8.} 

拦截器TokenInterceptor代码: 

1.public class TokenInterceptor extends HandlerInterceptorAdapter { 2.  3.   @Override 4.   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throwsException { 5.     if (handler instanceof HandlerMethod) { 6.       HandlerMethod handlerMethod = (HandlerMethod) handler; 7.       Method method = handlerMethod.getMethod(); 8.       Token annotation = method.getAnnotation(Token. class ); 9.       if (annotation != null ) { 10.         boolean needSaveSession = annotation.save(); 11.         if (needSaveSession) { 12.           request.getSession( false ).setAttribute( "token" , UUID.randomUUID().toString()); 13.         } 14.         boolean needRemoveSession = annotation.remove(); 15.         if (needRemoveSession) { 16.           if (isRepeatSubmit(request)) { 17.             return false ; 18.           } 19.           request.getSession( false ).removeAttribute( "token" ); 20.         } 21.       } 22.       return true ; 23.     } else { 24.       return super .preHandle(request, response, handler); 25.     } 26.   } 27.  28.   private boolean isRepeatSubmit(HttpServletRequest request) { 29.     String serverToken = (String) request.getSession( false ).getAttribute( "token" ); 30.     if (serverToken == null ) { 31.       return true ; 32.     } 33.     String clinetToken = request.getParameter( "token" ); 34.     if (clinetToken == null ) { 35.       return true ; 36.     } 37.     if (!serverToken.equals(clinetToken)) { 38.       return true ; 39.     } 40.     return false ; 41.   } 42.} 

然后在Spring MVC的配置文件里加入: 

1.<!-- 拦截器配置 --> 2.< mvc:interceptors > 3.   <!-- 配置Shiro拦截器,实现注册用户的注入 --> 4.   < mvc:interceptor > 5.     < mvc:mapping path = "/**" /> 6.     < bean class = "com.storezhang.video.shiro.ShiroInterceptor" /> 7.   </ mvc:interceptor > 8.   <!-- 配置Token拦截器,防止用户重复提交数据 --> 9.   < mvc:interceptor > 10.     < mvc:mapping path = "/**" /> 11.     < bean class = "com.storezhang.web.spring.TokenInterceptor" /> 12.   </ mvc:interceptor > 13.</ mvc:interceptors > 

相关代码已经注释,相信你能看懂。 关于这个方法的用法是:在需要生成token的controller上增加@Token(save=true),而在需要检查重复提交的controller上添加@Token(remove=true)就可以了。 另外,你需要在view里在form里增加下面代码: 

Html代码
1.<   input   type   =   "hidden"   name   =   "token"   value   =   "${token}"   /> 

在相关方法中加入注解 

1.@RequestMapping("/save") 2. @AvoidDuplicateSubmission(needRemoveToken = true) 3.  public synchronized ModelAndView save(ExecutionUnit unit, HttpServletRequest request, HttpServletResponse response) 4.      throws Exception { 5.  6.@RequestMapping("/edit") 7.  @AvoidDuplicateSubmission(needSaveToken = true) 8.  public ModelAndView edit(Integer id, HttpServletRequest request) throws Exception { 

获取【下载地址】 java后台框架 springmvc mybatis(oracle 和 mysql) HTML5 全新高大尚