session token防表单重提
1、表单页面初始化前,先在session存入一个token值,随后把token存放在表单页面隐藏表单域内,开始初始化;
在表单页初始化前,调用ajax请求,在后台生成token,并返回至表单页
1 function generateTokenId(){ 2 var url =appPath+'/page/placeOrder/order/generateTokenId'; 3 doAjax({ 4 url : url, 5 type : 'post', 6 async : false, 7 success : function(data) { 8 $("#tokenId").val(data); 9 } 10 }); 11 }
1 @RequestMapping(value = "/order/generateTokenId") 2 @ResponseBody 3 public String initCreateOrder(HttpServletRequest request){ 4 String uuid = UUID.randomUUID().toString(); 5 HttpSession session = request.getSession(); 6 session.setAttribute("UUID", uuid); 7 return uuid; 8 }
1 <!-- 提交按钮 --> 2 <div style="width:700px;margin-top: 5px;text-align: center"> 3 <input type="hidden" id="tokenId" /> 4 <a class="easyui-linkbutton" href="javascript:void(0)" iconCls="icon-ok" onclick="doCreateOrder()">提交订单</a> 5 6 <a class="easyui-linkbutton" href="javascript:void(0)" iconCls="icon-cancel" onclick="closeTab()">取消下单</a> 7 </div>
2、提交表单时,把隐藏表单域内token作为参数传到后台,与从session取出的token对比,若比对成功,则进行后续操作,且移除session中的token值;否则,算作重复提交,直接返回。
比对
1 public synchronized Map<String, Object> createOrder(HttpServletRequest request, OrderInfo orderInfo) { 2 boolean flag = this.isResubmit(request, orderInfo); 3 Map<String, Object> resuMap = new HashMap<String, Object>(); 4 if (flag) { 5 request.getSession().removeAttribute("UUID");//验证成功,及时移除 6 7 try { 8 String result = doCreateOrder(orderInfo); 9 if(result=='ok'){ 10 //继续后续操作 11 }else{ 12 String uuid = initCreateOrder(request);//token重置 13 resuMap.put("tokenId",uuid); 14 } 15 16 } catch (Exception e) { 17 } 18 } 19 }
1 private boolean isResubmit(HttpServletRequest request, OrderInfo orderInfo){ 2 boolean flag = false; 3 String uuid=null; 4 if (null!=request.getSession().getAttribute("UUID")) { 5 uuid = request.getSession().getAttribute("UUID").toString(); 6 } 7 String timeId = orderInfo.getTimeId();//timeId即为tokenId 8 if (null!=timeId && timeId.equals(uuid)) { 9 flag = true; 10 } 11 return flag; 12}
3、若后续操作中有些是对表单的验证,且验证通不过,表单不提交,停留在当前页,则需要重置session中token值,并且把新的token传入到表单页面隐藏表单域中(一般是ajax返回),否则表单内的值被会清空。
1 if(result=='ok'){ 2 //继续后续操作 3 }else{ 4 String uuid = initCreateOrder(request); 5 resuMap.put("tokenId",uuid); 6 }
1 @RequestMapping(value = "/order/generateTokenId") 2 @ResponseBody 3 public String initCreateOrder(HttpServletRequest request){ 4 String uuid = UUID.randomUUID().toString(); 5 HttpSession session = request.getSession(); 6 session.setAttribute("UUID", uuid); 7 return uuid; 8 }