springmvc中自己实现的token防表单重复提交,防止二次提交

1. [代码]如转载,请标明出处:http://www.oschina.net/code/snippet_100825_21906     

01 一:首先创建一个token处理类  ,这里的类名叫 TokenHandler
02  
03 private static Logger logger = Logger.getLogger(TokenHandler.class);
04  
05     static Map<String, String> springmvc_token = new HashMap<String, String>();
06      
07         //生成一个唯一值的token
08     @SuppressWarnings("unchecked")
09     public synchronized static String generateGUID(HttpSession session) {
10         String token = "";
11         try {
12             Object obj =  session.getAttribute("SPRINGMVC.TOKEN");
13             if(obj!=null)
14                 springmvc_token = (Map<String,String>)session.getAttribute("SPRINGMVC.TOKEN");
15             token = new BigInteger(165new Random()).toString(36)
16                     .toUpperCase();
17             springmvc_token.put(Constants.DEFAULT_TOKEN_NAME + "." + token,token);
18             session.setAttribute("SPRINGMVC.TOKEN", springmvc_token);
19             Constants.TOKEN_VALUE = token;
20  
21         catch (IllegalStateException e) {
22             logger.error("generateGUID() mothod find bug,by token session...");
23         }
24         return token;
25     }
26  
27        //验证表单token值和session中的token值是否一致
28     @SuppressWarnings("unchecked")
29     public static boolean validToken(HttpServletRequest request) {
30         String inputToken = getInputToken(request);
31  
32         if (inputToken == null) {
33             logger.warn("token is not valid!inputToken is NULL");
34             return false;
35         }
36  
37         HttpSession session = request.getSession();
38         Map<String, String> tokenMap = (Map<String, String>)           session.getAttribute("SPRINGMVC.TOKEN");
39         if (tokenMap == null || tokenMap.size() < 1) {
40             logger.warn("token is not valid!sessionToken is NULL");
41             return false;
42         }
43         String sessionToken = tokenMap.get(Constants.DEFAULT_TOKEN_NAME + "."
44                 + inputToken);
45         if (!inputToken.equals(sessionToken)) {
46             logger.warn("token is not valid!inputToken='" + inputToken
47                     "',sessionToken = '" + sessionToken + "'");
48             return false;
49         }
50         tokenMap.remove(Constants.DEFAULT_TOKEN_NAME + "." + inputToken);
51         session.setAttribute("SPRINGMVC.TOKEN", tokenMap);
52  
53         return true;
54     }
55  
56         //获取表单中token值
57     @SuppressWarnings("unchecked")
58     public static String getInputToken(HttpServletRequest request) {
59         Map params = request.getParameterMap();
60  
61         if (!params.containsKey(Constants.DEFAULT_TOKEN_NAME)) {
62             logger.warn("Could not find token name in params.");
63             return null;
64         }
65  
66         String[] tokens = (String[]) (String[]) params
67                 .get(Constants.DEFAULT_TOKEN_NAME);
68  
69         if ((tokens == null) || (tokens.length < 1)) {
70             logger.warn("Got a null or empty token name.");
71             return null;
72         }
73  
74         return tokens[0];
75     }

2. [代码] 如转载,请标明出处:http://www.oschina.net/code/snippet_100825_21906     

1 三 :这是我用到的常量:
2 public static String DEFAULT_TOKEN_MSG_JSP = "unSubmit.jsp" ;
3     public static String TOKEN_VALUE ;
4     public static String DEFAULT_TOKEN_NAME = "springMVC.token";

3. [代码] 如转载,请标明出处:http://www.oschina.net/code/snippet_100825_21906     

01 二: 自己实现一个自定义标签 这里我自定义的标签叫: <dy:token/>  (自定义标签的代码实现,我放csdn上了,不会的赶紧去下载,这里我不讲了),页面中使用如下:
02 1:引入标签库:<%@ taglib prefix="dy" uri="/dy-tags"%>
03 2:jsp页面中的表单,注意加上token标签!!!如下:
04  
05 index.jsp!!!
06  
07 <%@ taglib prefix="dy" uri="/dy-tags"%>
08 <html>
09   <head>
10     <title>spring mvc</title>
11   </head>
12   <body>         
13   welcome to spring mvc!<br/>
14  
15   <form name="mvcForm" action="indexSubmit.do" method="post">
16   <dy:token/>
17      username: <input name="username" type="text" value="${user.username}"/>
18      password: <input name="password" type="text" value="${user.password}"/>
19      email: <input name="email" type="text" value="${user.email}"/>
20        <input type="submit" value="提交">
21   </form>
22   </body>
23 </html>

4. [代码]如转载,请标明出处:http://www.oschina.net/code/snippet_100825_21906     

01 四: 我MyController类的以下2个方法要用到token,防止表单重复提交
02  
03 @RequestMapping(value = "index.do")
04     public String index(HttpServletRequest request) {
05          
06         return "index";
07     }
08  
09  
10 @RequestMapping(value = "indexSubmit.do", method = RequestMethod.POST)
11     public String indexSubmit(User user,HttpServletRequest request) {
12  
13         try {
14             myService.insert(user);
15             logger.info("info=新增成功");
16         catch (Exception e) {
17             logger.error("exception:" + e);
18         }

5. [代码] 如转载,请标明出处:http://www.oschina.net/code/snippet_100825_21906     

01 五:以下是我拦截器的实现,注意有两个拦截器,一个生成token,一个验证token。
02 /**
03  * @Title
04  * @author dengyang
05  * @date 2013-6-4
06  */
07 public class TokenHandlerInterceptor implements HandlerInterceptor{
08  
09  
10     public void afterCompletion(HttpServletRequest arg0,
11             HttpServletResponse arg1, Object arg2, Exception arg3)
12             throws Exception {
13     }
14  
15     public void postHandle(HttpServletRequest request, HttpServletResponse response,
16             Object arg2, ModelAndView arg3) throws Exception {
17         TokenHandler.generateGUID(request.getSession());
18     }
19  
20     public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
21             Object arg2) throws Exception {
22         return true;
23     }
24  
25 }
26  
27  
28  
29 /**
30  * @Title
31  * @author dengyang
32  * @date 2013-6-4
33  */
34 public class TokenValidInterceptor implements HandlerInterceptor{
35  
36     public void afterCompletion(HttpServletRequest request,
37             HttpServletResponse response, Object arg2, Exception arg3)
38             throws Exception {
39     }
40  
41     public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
42             Object arg2, ModelAndView arg3) throws Exception {
43          
44     }
45     public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
46             Object arg2) throws Exception {
47         if(!TokenHandler.validToken(request)){
48             response.sendRedirect(Constants.DEFAULT_TOKEN_MSG_JSP);
49             return false;
50         }
51     return true;
52     }
53  
54 }

6. [代码]如转载,请标明出处:http://www.oschina.net/code/snippet_100825_21906     

01 六:ok,这下面是我的spring拦截器配置
02  
03 <mvc:interceptor>
04             <mvc:mapping path="/index.do" />-->这个请求返回的是你有token的页面
05             <bean class="com.dengyang.interceptor.TokenHandlerInterceptor" />
06         </mvc:interceptor>
07         <mvc:interceptor>
08             <mvc:mapping path="/indexSubmit.do" />-->这个是提交请求
09             <bean class="com.dengyang.interceptor.TokenValidInterceptor" />
10         </mvc:interceptor>
11  
12  
13 七:ok,总体实现原理和struts的token标签类似,有问题请留言...

你可能感兴趣的:(springmvc中自己实现的token防表单重复提交,防止二次提交)