Token注解防止表单的重复提交

注解的一些基础:

参见http://blog.csdn.net/duo2005duo/article/details/50505884和

http://blog.csdn.net/duo2005duo/article/details/50511476这两篇文章

1,自定义一个注解@Token 用来标记需要防止重复提交的方法

 1 package com.bjca.framework.util;
 2 /**
 3  * <p>
 4 *关于这个方法的用法是:
 5 *在需要生成token的controller上增加@Token(save=true),
 6 *而在需要检查重复提交的controller上添加@Token(remove=true)就可以了
 7 *另外,你需要在view里在form里增加下面代码:
 8 *<input type="hidden" name="token" value="${token}">
 9  * 此时会在拦截器中验证是否重复提交
10  * </p>
11  *
12  */
13 import java.lang.annotation.*;
14 
15 @Target(ElementType.METHOD)
16 @Retention (RetentionPolicy.RUNTIME)
17 public @interface Token {
18  
19      boolean save() default false ;
20  
21      boolean remove() default false ;
22 }

 

2,自定义一个针对该注解的拦截器 TokenInterceptor 

 1 package com.bjca.framework.util;
 2 
 3 import org.apache.commons.logging.Log;
 4 import org.apache.commons.logging.LogFactory;
 5 import org.springframework.web.method.HandlerMethod;
 6 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 7 
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 import java.lang.reflect.Method;
11 import java.util.UUID;
12 
13 public class TokenInterceptor extends HandlerInterceptorAdapter {
14     public static Log log = LogFactory.getLog(TokenInterceptor.class);
15      @Override
16      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
17           System.out.println(handler.getClass());
18          if (handler instanceof HandlerMethod) {
19              HandlerMethod handlerMethod = (HandlerMethod) handler;
20              Method method = handlerMethod.getMethod();
21              Token annotation = method.getAnnotation(Token. class );
22            
23              if (annotation != null ) {
24                  boolean needSaveSession = annotation.save();
25                  if (needSaveSession) {
26                      String uuid=UUID.randomUUID().toString();
27                         log.debug("提交生成除令牌"+uuid);
28                      request.getSession( false ).setAttribute( "token" , uuid);
29                  }
30                  boolean needRemoveSession = annotation.remove();
31                  if (needRemoveSession) {
32                      if (isRepeatSubmit(request)) {
33                          return false ;
34                      }
35                      log.debug("提交移除令牌"+request.getSession().getAttribute("token" ));
36                      request.getSession( false ).removeAttribute( "token" );
37                  }
38              }
39              return true ;
40          } else {
41              return super .preHandle(request, response, handler);
42          }
43      }
44  
45      private boolean isRepeatSubmit(HttpServletRequest request) {
46          String serverToken = (String) request.getSession( false ).getAttribute( "token" );
47          if (serverToken == null ) {
48              return true ;
49          }
50          String clinetToken = request.getParameter( "token" );
51          if (clinetToken == null ) {
52              return true ;
53          }
54          if (!serverToken.equals(clinetToken)) {
55              return true ;
56          }
57          return false ;
58      }
59 }

3,在spring MVC的配置文件里注册该拦截器

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:mvc="http://www.springframework.org/schema/mvc" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xmlns:p="http://www.springframework.org/schema/p" 
 6     xmlns:context="http://www.springframework.org/schema/context"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 8         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
 9         http://www.springframework.org/schema/context 
10         http://www.springframework.org/schema/context/spring-context-4.0.xsd 
11         http://www.springframework.org/schema/mvc 
12         http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"
13     >
14     <!-- 对spring org.lxh包下所有注解扫描 -->
15     <context:component-scan base-package="com.xxx">
16         <context:exclude-filter type="annotation"  expression="org.springframework.stereotype.Repository" />
17     </context:component-scan>
20     <!-- 支持spring mvc新的注解类型 详细spring3.0手册 15.12.1 mvc:annotation-driven-->
21     <mvc:annotation-driven />
22     
23     <bean  id="viewResolver"
24             class="org.springframework.web.servlet.view.InternalResourceViewResolver">
25             <!-- 为了使用JSTL Tag修改默认的viewClass属性 -->
26             <property
27                   name="viewClass"
28                   value="org.springframework.web.servlet.view.JstlView" />
29             <property
30                   name="prefix"
31                   value="/WEB-INF/views/" />
32             <property
33                   name="suffix"
34                   value=".jsp"></property>
35             <property
36                   name="order"
37                   value="1"></property>
38         </bean>
39    <!-- 拦截器 -->
40     <mvc:interceptors>
41        <!-- 用户登录拦截 -->
42         <bean class="com.xx.xxx.filter.StageSecurityInterceptor">
43             <property name="patterns" >
44                 <list>
45                     <value>.*/console/.*\.jhtml</value>
46                     <value>.*/center/.*\.jhtml</value>
47                   
48                 </list>
49             </property>
50             <property name="loginView">
51                 <value>/manage.jsp</value>
52             </property>
53         </bean>
54          <!-- 配置Token拦截器,防止用户重复提交数据 -->
55         <mvc:interceptor>
56             <mvc:mapping path="/**"/>
57             <bean class="com.xxx.framework.util.TokenInterceptor"/>
58         </mvc:interceptor>
59     </mvc:interceptors>
60     <!--  
61      <bean id="viewResolver"
62           class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
63         <property name="basenames">
64             <list>
65                 <value>views-stage</value>
66             </list>
67         </property>
68     </bean>
69     -->
70 </beans>

 4,演示demo

4.1,在跳转至某个需要加上@Token(save = true)

1     @RequestMapping("/personalForm.jhtml")
2   @Token(save = true)
3     public String personalForm(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
4         Account account = Account.sessionAccount();
5         if (account == null) {
6             return "redirect:/login.jsp";
7         }
8       //..........业务..............
9   }    

 

 4.2,在上个Controller 跳转的方法上加入${Token} 

 1 <div class="main clearfix nav center regist copyright_main5">
 2         <h3 class="registTitle">填写身份信息</h3>
 3         <img alt="" src="<c:url value='/platform/stage/image/regist/wave.png'/>"><br /> <img src="<c:url value='/platform/stage/image/portals/regist-info.png'/>"></img>
 4         <c:if test="${personalInfoForm.checkState eq 2}">
 5         <br/>
 6         <div>
 7         <font color="red" size="2"><span>身份认证意见:${personalInfoForm.checkOpnion}</span></font>
 8         </div>
 9         </c:if>
10         <form autocomplete="off" style="margin: 0;" id="form1" method="post" name="personalInfoForm" action="<c:url value='/center/member/savePersonalInfo.jhtml'/>" enctype="multipart/form-data">
11             <input type="hidden" value="${personalInfoForm.id}" name="id" />
12             <input type="hidden" name="token" value="${token}">             

 4.3,在表单提交方法的地方加上注解 @Token(remove = true)

 1 @RequestMapping(value = "/savePersonalInfo.jhtml", method = {RequestMethod.POST})
 2     @Token(remove = true)
 3     public String savePersonalInfo(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap, PersonalInfo personalInfoForm) throws Exception {
 4         DateFormat fm = new SimpleDateFormat("yyyy-MM-dd");
 5         Date birthday = fm.parse(request.getParameter("birthday2"));
 6         personalInfoForm.setBirthday(birthday);
 7       
 8         Account account = Account.sessionAccount();
 9         if(account==null){
10             return "redirect:/login.jsp";
11         }
12     //.....................业务.........................
13 }    

 5,完成了。

转载于:https://www.cnblogs.com/Pikzas/p/6008047.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机主机风扇安装方法,电脑机箱怎么安装风扇减震胶钉保护主板cup?

炎炎夏日&#xff0c;是时候给你的爱机清清灰&#xff0c;特别是对于机箱散热不好的朋友就需要给电脑机箱装上几个风力强劲的风扇&#xff0c;这样可以大大减少CPU、主板等的老化时间&#xff0c;延长爱机的寿命。现在机箱风扇大都使用橡胶拉钉(或者叫减震钉、固定钉)安装&…

2个css特效冲突了怎么办_患上类风湿病怎么办?2个方法拿走不谢

类风湿是一种常见的疾病&#xff0c;类风湿关节炎简称为类风湿&#xff0c;是一个累及周围关节为主的多系统性炎症性自身免疫病&#xff0c;患者的关节疼痛、肿胀&#xff0c;而且易反复发作。那么&#xff0c;得了类风湿病怎么办&#xff1f;得了类风湿病怎么办目前&#xff0…

将项目导入eclipse中出现的jsp页面报错

图片摘自百度经验&#xff0c;实在是每次都会忘了步骤&#xff0c;每次都得重新百度&#xff0c;所以索性自己总结到博客中&#xff0c;下次如果还记不住就直接从博客中看。原谅我实在学渣&#xff0c;呜呜~~~~(>_<)~~~~ 转载于:https://www.cnblogs.com/yangyufan/p/600…

怎样让计算机恢复到桌面上,如何把电脑桌面恢复成原样.怎么办?

此方案适用XP\VISTA\WIN7系统【问题描述】&#xff1a;桌面图标太多【原因分析】&#xff1a;1.下载的软件快捷方式放到桌面没有进行整理;2.在桌面上放置太多的文件【简易步骤】&#xff1a;【360安全卫士】—【功能大全】—【桌面管理】—【整理桌面个人资料】【解决方案】&am…

中装订线位置_企业宣传画册、产品目录常用的装订方法

印刷是个专业活&#xff0c;特别是画报、画册这些种类多&#xff0c;要求高。下面介绍一下最常用到的三种装订方法&#xff1a;骑马订骑马订(saddlestitch)英文是马鞍的意思&#xff0c;取其于装订之时&#xff0c;将摺好的页子如同为马匹上鞍一般的动作&#xff0c;配至装订机…

使用Hibernate在CQRS读取模型中进行快速开发

在这篇文章中&#xff0c;我将分享一些在CQRS读取模型中使用Hibernate工具进行快速开发的技巧。 为什么要休眠&#xff1f; 休眠非常流行。 从外观上看&#xff0c;它也很容易&#xff0c;而从内部看&#xff0c;它却相当复杂。 它可以很容易地开始使用&#xff0c;而无需进行…

iOS - Swift NSData 数据

本文目录 前言1、NSData 的创建2、数据的长度3、数据的获取4、NSData 的比较5、NSData 的存储6、NSData 与 字符串 的相互转换7、NSData 与 Base64编码字符串 的相互转换回到顶部前言 public class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding public cla…

美国东北大学khoury计算机学院,2021年美国东北大学计算机研究生专业有哪些?入学要求高吗?...

在“唯才是用”的时代&#xff0c;高新科技行业人才成为了社会的主流&#xff0c;各行各业也都急需计算机相关人才&#xff0c;美国可谓是计算机领域的鼻祖&#xff0c;拥有着非常先进的互联网技术&#xff0c;除此之外&#xff0c;几乎每所大学都开设了计算机专业&#xff0c;…

c++进制转换代码_轻松实现C/C++各种常见进制相互转换,你还不会你就落后了

这篇文章主要介绍了轻松实现C/C各种常见进制相互转换&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧其它进制转为十进制在实现这个需求之前&#xff0c;先简单介绍一…

我的博客是怎么自定义的

第一步&#xff0c;打开设置&#xff0c;一切都在设置里进行&#xff0c;让我们从头到尾&#xff0c;从左到右一步步讲。 1.头像 此头像不是账号头像&#xff0c;是标题那里放图片当头像 <img src"你头像的地址" alt"" /> 步骤&#xff1a;将你喜欢…

2017年计算机三级网络技术试题,2017年计算机三级网络技术考前试题及答案(8)

三、应用题(共20分)请根据下图所示网络结构回答问题。1&#xff0e;填写路由器RG的路由表项(每空2分&#xff0c;共l0分)。2&#xff0e;如果该网络内服务器群的IP地址为58&#xff0e;45&#xff0e;57&#xff0e;11-58&#xff0e;45&#xff0e;57&#xff0e;25&#xff0…

byte数组转为string_String类

API ----StringBufferjava.lang.Object 继承者 java.lang.Stringpublic final class String extends Object implements Serializable, Comparable<String>, CharSequenceYuSLi&#xff1a;String类速查速记​zhuanlan.zhihu.comYuSLi&#xff1a;补充&#xff1a;String…

AngularJS的学习笔记(二)

只给自己看的。 AngularJS 表达式 angularjs 使用表达式将数据绑定到html中。 AngularJS 表达式写在双大括号内&#xff1a;{{ expression }}。 AngularJS 表达式把数据绑定到 HTML&#xff0c;这与 ng-bind 指令有异曲同工之妙。 AngularJS 将在表达式书写的位置"输出&qu…

亚型多态性应用于元组的危险

Java 8具有lambda和stream&#xff0c;但是没有元组&#xff0c;这真是令人遗憾 。 这就是为什么我们在jOOλ中实现了元组-Java 8缺少的部分 。 元组确实是无聊的值类型容器。 本质上&#xff0c;它们只是这些类型的枚举&#xff1a; public class Tuple2<T1, T2> {publ…

广西计算机二级450034考点,广西计算机等级考试报名地点

2010年下半年全国计算机等级考试时间是2010年9月18日至22日&#xff0c;第一天上午考笔试&#xff0c;上机考试从笔试的当天下午开始(一级从上午开始)。2010年下半年全国计算机等级考试报名时间已经开始&#xff01;如果您是在校生&#xff0c;去学校相关报名处报名最方便&…

HBuilder完成webApp入门(3) 关于webview (转)

个人认为WebView是 html5 API的一个非常重要的部分。 WebView 的帮助文档http://www.html5plus.org/doc/zh_cn/webview.html 为什么对WebView的掌握很重要&#xff1f;因为它是一个HTML5 APP的基础。刚刚学习HBuilder的同学一般会将重点放在 mui 组件上。mui 提供了很多默认的方…

ca证书 csr_linux下使用openssl生成 csr crt CA证书

证书文件生成:一.服务器端1.生成服务器端 私钥(key文件);openssl genrsa -des3 -out server.key 1024运行时会提示输入密码,此密码用于加密key文件(参数des3是加密算法,也可以选用其他安全的算法),以后每当需读取此文件(通过openssl提供的命令或API)都需输入口令.如果不要口…

佛山市南海技师学校计算机类,佛山南海信息技术学校2021年有哪些专业

即将面临毕业的时候&#xff0c;同学们都要选择学校&#xff0c;都要选择专业就读&#xff0c;至于选择什么&#xff0c;就是一大难题了。学习是重要的事情&#xff0c;选择更是件大事。小编整理了学校的招生专业详情&#xff0c;仅供参考。佛山南海信息技术学校专业名单&#…

java nio拷贝文件_Java 7 – NIO文件革命

java nio拷贝文件Java 7&#xff08;“项目代币”&#xff09;已于去年7月问世。 此版本中的新增功能很有用&#xff0c;例如&#xff0c;尝试资源-从try块中自动处理可关闭的资源&#xff0c;switch语句中的字符串&#xff0c;用于异常的multicatch以及用于处理泛型的<>…

getresource 路径转义_java中的相对路径和绝对路径

(转载)1.基本概念的理解绝对路径&#xff1a;绝对路径就是你的主页上的文件或目录在硬盘上真正的路径&#xff0c;(URL和物理路径)例如&#xff1a;C:\xyz\test.txt 代表了test.txt文件的绝对路径。http://www.sun.com/index.htm也代表了一个URL绝对路径。相对路径&#xff1a;…