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(165, new 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 | } |
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"; |
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> |
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 | } |
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 | } |
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標籤相似,有問題請留言... |