您的位置:首页 > 编程语言 > Java开发

Spring MVC拦截器+注解方式实现防止表单重复提交

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

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

注解Token代码:java源码 

Java代码 复制代码 收藏代码
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代码:

Java代码 复制代码 收藏代码
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的配置文件里加入:

Xml代码 复制代码 收藏代码
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}"     />

在相关方法中加入注解

Java代码 复制代码 收藏代码
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 {

已经完成了,去试试看你的数据还能重复提交了吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: