Spring MVC拦截器+诠注方式实现防止表单重复提交
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的配置文件里加入: