代码简介 springmvc中自己实现的token防表单重复提交,防止二次提交!!!代码片段 一:首先创建一个token处理类 ,这里的类名叫 TokenHandler private static Logger logger = Logger.getLogger(TokenHandler.class); static Map<String, String> springmvc_token = new HashMap<String, String>(); //生成一个唯一值的token @SuppressWarnings("unchecked") public synchronized 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"); token = new BigInteger(165, new Random()).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..."); } return token; } //验证表单token值和session中的token值是否一致 @SuppressWarnings("unchecked") public static boolean validToken(HttpServletRequest request) { String inputToken = getInputToken(request); if (inputToken == null) { logger.warn("token is not valid!inputToken is NULL"); return false; } 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"); return false; } String sessionToken = tokenMap.get(Constants.DEFAULT_TOKEN_NAME + "." + inputToken); if (!inputToken.equals(sessionToken)) { logger.warn("token is not valid!inputToken='" + inputToken + "',sessionToken = '" + sessionToken + "'"); return false; } tokenMap.remove(Constants.DEFAULT_TOKEN_NAME + "." + inputToken); session.setAttribute("SPRINGMVC.TOKEN", tokenMap); return true; } //获取表单中token值 @SuppressWarnings("unchecked") public static String getInputToken(HttpServletRequest request) { Map params = request.getParameterMap(); if (!params.containsKey(Constants.DEFAULT_TOKEN_NAME)) { logger.warn("Could not find token name in params."); return null; } 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."); return null; } return tokens[0]; } 代码片段 三 :这是我用到的常量: public static String DEFAULT_TOKEN_MSG_JSP = "unSubmit.jsp" ; public static String TOKEN_VALUE ; public static String DEFAULT_TOKEN_NAME = "springMVC.token"; 代码片段 二: 自己实现一个自定义标签 这里我自定义的标签叫: <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> 代码片段 四: 我MyController类的以下2个方法要用到token,防止表单重复提交 @RequestMapping(value = "index.do") public String index(HttpServletRequest request) { return "index"; } @RequestMapping(value = "indexSubmit.do", method = RequestMethod.POST) public String indexSubmit(User user,HttpServletRequest request) { try { myService.insert(user); logger.info("info=新增成功"); } catch (Exception e) { logger.error("exception:" + e); } 代码片段 五:以下是我拦截器的实现,注意有两个拦截器,一个生成token,一个验证token。 /** * @Title * @author dengyang * @date 2013-6-4 */ public class TokenHandlerInterceptor implements HandlerInterceptor{ public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3) throws Exception { TokenHandler.generateGUID(request.getSession()); } public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { return true; } } /** * @Title * @author dengyang * @date 2013-6-4 */ public class TokenValidInterceptor implements HandlerInterceptor{ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) throws Exception { } public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { } public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { if(!TokenHandler.validToken(request)){ response.sendRedirect(Constants.DEFAULT_TOKEN_MSG_JSP); return false; } return true; } } 代码片段 六:ok,这下面是我的spring拦截器配置 <mvc:interceptor> <mvc:mapping path="/index.do" />-->这个请求返回的是你有token的页面 <bean class="com.dengyang.interceptor.TokenHandlerInterceptor" /> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/indexSubmit.do" />-->这个是提交请求 <bean class="com.dengyang.interceptor.TokenValidInterceptor" /> </mvc:interceptor> 七:ok,总体实现原理和struts的token标签类似,有问题请留言... |
|