[转] Spring MVC实现token防止重复提交
转载自 开源中国社区
1 一:首先创建一个token处理类 ,这里的类名叫 TokenHandler 2 3 private static Logger logger = Logger.getLogger(TokenHandler.class); 4 5 static Map<String, String> springmvc_token = null; 6 7 //生成一个唯一值的token 8 @SuppressWarnings("unchecked") 9 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 else 16 springmvc_token = new HashMap<String, String>() 17 token = new BigInteger(165, new Random()).toString(36) 18 .toUpperCase(); 19 springmvc_token.put(Constants.DEFAULT_TOKEN_NAME + "." + token,token); 20 session.setAttribute("SPRINGMVC.TOKEN", springmvc_token); 21 Constants.TOKEN_VALUE = token; 22 23 } catch (IllegalStateException e) { 24 logger.error("generateGUID() mothod find bug,by token session..."); 25 } 26 return token; 27 } 28 29 //验证表单token值和session中的token值是否一致 30 @SuppressWarnings("unchecked") 31 public static boolean validToken(HttpServletRequest request) { 32 String inputToken = getInputToken(request); 33 34 if (inputToken == null) { 35 logger.warn("token is not valid!inputToken is NULL"); 36 return false; 37 } 38 39 HttpSession session = request.getSession(); 40 Map<String, String> tokenMap = (Map<String, String>) session.getAttribute("SPRINGMVC.TOKEN"); 41 if (tokenMap == null || tokenMap.size() < 1) { 42 logger.warn("token is not valid!sessionToken is NULL"); 43 return false; 44 } 45 String sessionToken = tokenMap.get(Constants.DEFAULT_TOKEN_NAME + "." 46 + inputToken); 47 if (!inputToken.equals(sessionToken)) { 48 logger.warn("token is not valid!inputToken='" + inputToken 49 + "',sessionToken = '" + sessionToken + "'"); 50 return false; 51 } 52 tokenMap.remove(Constants.DEFAULT_TOKEN_NAME + "." + inputToken); 53 session.setAttribute("SPRINGMVC.TOKEN", tokenMap); 54 55 return true; 56 } 57 58 //获取表单中token值 59 @SuppressWarnings("unchecked") 60 public static String getInputToken(HttpServletRequest request) { 61 Map params = request.getParameterMap(); 62 63 if (!params.containsKey(Constants.DEFAULT_TOKEN_NAME)) { 64 logger.warn("Could not find token name in params."); 65 return null; 66 } 67 68 String[] tokens = (String[]) (String[]) params 69 .get(Constants.DEFAULT_TOKEN_NAME); 70 71 if ((tokens == null) || (tokens.length < 1)) { 72 logger.warn("Got a null or empty token name."); 73 return null; 74 } 75 76 return tokens[0]; 77 }
1 二: 自己实现一个自定义标签 这里我自定义的标签叫: <dy:token/> (自定义标签的代码实现,我放csdn上了,不会的赶紧去下载,这里我不讲了),页面中使用如下: 2 1:引入标签库:<%@ taglib prefix="dy" uri="/dy-tags"%> 3 2:jsp页面中的表单,注意加上token标签!!!如下: 4 5 index.jsp!!! 6 7 <%@ taglib prefix="dy" uri="/dy-tags"%> 8 <html> 9 <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>
1 四: 我MyController类的以下2个方法要用到token,防止表单重复提交 2 3 @RequestMapping(value = "index.do") 4 public String index(HttpServletRequest request) { 5 6 return "index"; 7 } 8 9 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 }
1 五:以下是我拦截器的实现,注意有两个拦截器,一个生成token,一个验证token。 2 /** 3 * @Title 4 * @author dengyang 5 * @date 2013-6-4 6 */ 7 public class TokenHandlerInterceptor implements HandlerInterceptor{ 8 9 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 }
1 六:ok,这下面是我的spring拦截器配置 2 3 <mvc:interceptor> 4 <mvc:mapping path="/index.do" />-->这个请求返回的是你有token的页面 5 <bean class="com.dengyang.interceptor.TokenHandlerInterceptor" /> 6 </mvc:interceptor> 7 <mvc:interceptor> 8 <mvc:mapping path="/indexSubmit.do" />-->这个是提交请求 9 <bean class="com.dengyang.interceptor.TokenValidInterceptor" /> 10 </mvc:interceptor> 11 12 13 七:ok,总体实现原理和struts的token标签类似,有问题请至 开源中国社区 留言
转载自 开源中国社区

浙公网安备 33010602011771号