【spring mvc】springmvc中自己实现的token防表单重复提交,防止二次提交(二)

来源:互联网 发布:ramin djawadi 知乎 编辑:程序博客网 时间:2024/06/10 15:35

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

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
四: 我MyController类的以下2个方法要用到token,防止表单重复提交
 
@RequestMapping(value = "index.do")
    publicString index(HttpServletRequest request) {
         
        return"index";
    }
 
 
@RequestMapping(value = "indexSubmit.do", method = RequestMethod.POST)
    publicString indexSubmit(User user,HttpServletRequest request) {
 
        try{
            myService.insert(user);
            logger.info("info=新增成功");
        }catch(Exception e) {
            logger.error("exception:"+ e);
        }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
五:以下是我拦截器的实现,注意有两个拦截器,一个生成token,一个验证token。
/**
 * @Title
 * @author dengyang
 * @date 2013-6-4
 */
publicclass TokenHandlerInterceptor implementsHandlerInterceptor{
 
 
    publicvoid afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throwsException {
    }
 
    publicvoid postHandle(HttpServletRequest request, HttpServletResponse response,
            Object arg2, ModelAndView arg3) throwsException {
        TokenHandler.generateGUID(request.getSession());
    }
 
    publicboolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object arg2) throwsException {
        returntrue;
    }
 
}
 
 
 
/**
 * @Title
 * @author dengyang
 * @date 2013-6-4
 */
publicclass TokenValidInterceptor implementsHandlerInterceptor{
 
    publicvoid afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object arg2, Exception arg3)
            throwsException {
    }
 
    publicvoid postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throwsException {
         
    }
    publicboolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object arg2) throwsException {
        if(!TokenHandler.validToken(request)){
            response.sendRedirect(Constants.DEFAULT_TOKEN_MSG_JSP);
            returnfalse;
        }
    returntrue;
    }
 
}

6. [代码]如转载,请标明出处:http://www.oschina.net/code/snippet_100825_21906     跳至 [1] [2] [3] [4][5] [6] [全屏预览]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
六:ok,这下面是我的spring拦截器配置
 
<mvc:interceptor>
            <mvc:mapping path="/index.do"/>-->这个请求返回的是你有token的页面
            <beanclass="com.dengyang.interceptor.TokenHandlerInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/indexSubmit.do"/>-->这个是提交请求
            <beanclass="com.dengyang.interceptor.TokenValidInterceptor"/>
        </mvc:interceptor>
 
 
七:ok,总体实现原理和struts的token标签类似,有问题请留言...
0 0
原创粉丝点击