java 金额支付怎么防止防止刷新重复提交post

3470人阅读
四年的沉积(79)
import java.io.IOE
import java.security.MessageD
import java.security.NoSuchAlgorithmE
import java.util.R
import javax.servlet.ServletE
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import sun.misc.BASE64E
//产生表单
public class FormServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//产生随机数
TokenProcessor tp=TokenProcessor.getInstance();
String token=tp.generateToken();
request.getSession().setAttribute(&token&, token);
request.getRequestDispatcher(&/form.jsp&).forward(request, response);
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
class TokenProcessor//令牌
* 1.把构造函数私有
* 2.自己创建一个
* 3.对外暴露一个方法,允许获取上面创建的对象
private static final TokenProcessor instance=new TokenProcessor();
private TokenProcessor(){}
public static TokenProcessor getInstance()
public String generateToken()
String token=System.currentTimeMillis()+new Random().nextInt()+&&;
MessageDigest md=MessageDigest.getInstance(&md5&);
byte[] md5=md.digest(token.getBytes());
//base64编码
BASE64Encoder encoder=new BASE64Encoder();
return encoder.encode(md5);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
&%@ page language=&java& import=&java.util.*& pageEncoding=&UTF-8&%&
String path = request.getContextPath();
String basePath = request.getScheme()+&://&+request.getServerName()+&:&+request.getServerPort()+path+&/&;
&!DOCTYPE HTML PUBLIC &-//W3C//DTD HTML 4.01 Transitional//EN&&
&base href=&&%=basePath%&&&
&title&My JSP 'form.jsp' starting page&/title&
&meta http-equiv=&pragma& content=&no-cache&&
&meta http-equiv=&cache-control& content=&no-cache&&
&meta http-equiv=&expires& content=&0&&
&meta http-equiv=&keywords& content=&keyword1,keyword2,keyword3&&
&meta http-equiv=&description& content=&This is my page&&
&link rel=&stylesheet& type=&text/css& href=&styles.css&&
&form action=&/Session/DoForm& method=&post&&
&input type=&hidden& name=&token& value=&${token}&&
用户名:&input type=&text& name=&userName&&
&input type=&submit& value=&提交&&
import java.io.IOE
import javax.servlet.ServletE
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
* Servlet implementation class DoForm
* 处理表单提交的请求
public class DoForm extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*String userName=request.getParameter(&userName&);
Thread.sleep(1000*3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(&向数据库提交注册用户...&);
boolean b=isTokenValid(request);
System.out.println(&请不要重复提交!&);
request.getSession().removeAttribute(&token&);
System.out.println(&向数据库中注册用户==&);
private boolean isTokenValid(HttpServletRequest request) {
String client_token=request.getParameter(&token&);
if(client_token==null)
String server_token=(String)request.getSession().getAttribute(&token&);
if(server_token==null)
if(!client_token.equals(server_token))
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:306156次
积分:5088
积分:5088
排名:第3402名
原创:202篇
转载:16篇
评论:96条
文章:16篇
阅读:58068
文章:12篇
阅读:8627
文章:13篇
阅读:7373
文章:48篇
阅读:51478
(9)(9)(8)(12)(5)(6)(20)(12)(4)(2)(6)(3)(1)(1)(1)(2)(8)(16)(16)(6)(2)(1)(13)(29)(2)(16)(10)下次自动登录
现在的位置:
& 综合 & 正文
java web开发时防止刷新后的重复提交
在java web开发过程中大家经常都会遇到页面刷新后重复提交导致数据库数据重复的情况出现。
那么,如何避免重复提交数据的情况出现呢?如下,是在jsp中解决重复提交的一种方式。
String timeStamp = String.valueOf(new java.util.Date().getTime());
String tokenStr = session.getId()+timeS
String sesValue = session.getValue("CONTROL_REFRESH").toString();
String reqValue = request.getParameter("tokenStr");
if(!sesValue.equals(reqValue)){
out.print("不能重复提交数据!");
session.setAttribute("CONTROL_REFRESH",tokenStr);
将以上代码放到需要解决刷新后重复提交问题的jsp页面&%%&中即可。
&&&&推荐文章:
【上篇】【下篇】当前访客身份:游客 [
沉淀 积累 坚持不懈
:引用来自“hgzlpmg”的评论sudo ./bin/startup....
:还有 我看了很多教程,包括配置jdk的教程,凡是让...
:sudo ./bin/startup.sh 这一步提示找不到命令...
:引用来自“未明儿”的评论“父类的构造函数可以作...
:“父类的构造函数可以作为子类的默认构造函数,但...
:非常有帮助。。谢谢!
:好文,比较详细
:引用来自“疯狂的舌头”的评论 在网易浏览新闻图...
:在网易浏览新闻图片时不能回退。 每次回退最后一...
今日访问:18
昨日访问:43
本周访问:18
本月访问:1977
所有访问:37371
javaweb开发之防止重复提交
发表于2年前( 17:13)&&
阅读(1911)&|&评论()
0人收藏此文章,
一、产生表单重复提交可能的情况
1. 由于服务器缓慢或网络延迟等原因,导致用户重复点击提交按钮。
2. 使用forward方式已经提交成功,再次刷新成功页面导致重复提交。
3. 已经提交成功,通过回退,再次点击提交按钮。
在firefox,重复提交到同一地址无效。
回退后,刷新表单页面,再次提交这时不是重复提交,而是发送新的请求。
使用redirect方式重定向到成功页面不会出现重复提交的问题。
二、解决方式
要避免重复刷新、重复提交、以及防止后退的问题的,需要区分如何处理以及在哪里处理。处理的方式无非是客户端或者服务器端两种。对于不同的位置处理的方式也是不同的,但是任何客户端(尤其是B/S端)的处理都是不可信任的,最好的也是最应该的是服务器端的处理方法。
1. 客户端处理
javascript只能处理服务器繁忙时的用户多次提交。
1.1 重复刷新、重复提交
方法一:设置一个变量,只允许提交一次。
&script language="javascript"&
var checkSubmitFlag =
function checkSubmit() {
if (checkSubmitFlag == true) {
checkSubmitFlag =
document.ondblclick = function docondblclick() {
window.event.returnValue =
document.onclick = function doc {
if (checkSubmitFlag) {
window.event.returnValue =
&html:form action="myAction.do" method="post" onsubmit="return checkSubmit();"&
方法二:将提交按钮或者image置为disable
&html:form action="myAction.do" method="post"
onsubmit="getElById('submitInput').disabled ="&
&html:image styleId="submitInput" src=\'#\'" /ok_b.gif" border="0" /&
&/html:form&
1.2 防止用户后退
这里的方法是千姿百态,有的是更改浏览器的历史纪录的,比如使用window.history.forward()方法;有的是“用新页面的URL替换当前的历史纪录,这样浏览历史记录中就只有一个页面,后退按钮永远不会变为可用。”比如使用javascript:location.replace(this.href); event.returnValue=
2. 服务器端处理
实现思路:
使用UUID生成随机数,借助session,使用令牌机制来实现。
服务器在每次产生的页面FORM表单中分配一个唯一标识号(这个唯一标识号可以使用UUID产生),将这个唯一标识号保存在该FORM表单中的一个隐藏域中。同时在当前用户的session域中保存该唯一标识符。当用户提交表单时,服务器接收程序比较FORM表单隐藏字段中的标识号和存储在当前用户session域中的标识号是否一致。如果一致,则处理表单数据,同时清除当前用户session域中存储的标识号。如果不一致,服务器接收程序不处理提交的表单请求。
使用以上方式会导致编辑页面只能有一个。解决方案是:为每一个提交的form表单增加一个属性提交区别来源于不同表单。
示例主要代码:
UUIDToken.java
package mon.
import java.util.UUID;
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpS
public class UUIDToken {
public static final String UUIDTOKEN_IN_REQUEST = "UUIDTOKEN_IN_REQUEST";
public static final String UUIDTOKEN_IN_SESSION = "UUIDTOKEN_IN_SESSION";
public static final String UUIDTOKEN_FORMID_IN_REQUEST = "UUIDTOKEN_FORMID_IN_REQUEST";
private static UUIDToken instance = new UUIDToken();
private UUIDToken(){
public static UUIDToken getInstance(){
* 生成UUIDToken
public void generateUUIDToken(HttpServletRequest req){
HttpSession session = req.getSession(true);
UUID uuid = UUID.randomUUID();
UUID uuid_form_id = UUID.randomUUID();
req.setAttribute(UUIDTOKEN_IN_REQUEST, uuid.toString());
req.setAttribute(UUIDTOKEN_FORMID_IN_REQUEST, uuid_form_id.toString());
session.setAttribute(uuid_form_id.toString(), uuid.toString());
* 是否重复提交
* 1,如果没有session,验证失败
* 2,如果session中没有UUIDTOKEN_IN_SESSION,验证失败
* 3,如果session中的UUIDTOKEN_IN_SESSION和表单中的UUIDTOKEN_IN_REQUEST不相等,验证失败
public boolean isRepeatSubmit(HttpServletRequest req){
//是否重复提交(默认true重复提交)
boolean isRepeatSubmit =
HttpSession session = req.getSession(false);
if(session != null){
String uuidToken_formId = req.getParameter("UUIDTOKEN_FORMID_IN_REQUEST");
if(StringUtil.isNotBlank(uuidToken_formId)){
String uuidToken_in_session = (String)session.getAttribute(uuidToken_formId);
if(StringUtil.isNotBlank(uuidToken_in_session)){
String uuidToken_in_request = req.getParameter(UUIDTOKEN_IN_REQUEST);
if(uuidToken_in_session.equals(uuidToken_in_request)){
isRepeatSubmit =
//清除session中的uuid防重复提交令牌
session.removeAttribute(uuidToken_formId);
return isRepeatS
} ProductServlet.java
package cn.heimar.demo.
import java.io.IOE
import java.math.BigD
import java.util.L
import java.util.UUID;
import javax.servlet.ServletE
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpS
import mon.core.dao.DaoF
import mon.util.PageR
import mon.util.StringU
import mon.util.UUIDT
import cn.heimar.demo.dao.IProductD
import cn.heimar.demo.dao.ISupplierD
import cn.heimar.demo.dao.query.ProductQueryO
import cn.heimar.demo.domain.P
import cn.heimar.demo.domain.S
public class ProductServlet extends HttpServlet {
private static final long serialVersionUID = -4582082L;
private IProductDao productD
private ISupplierDao supplierD
private boolean hasLength(String s) {
return s != null && !"".equals(s.trim());
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String cmd = req.getParameter("cmd");
if ("edit".equals(cmd)) {
// 转向添加页面
String id = req.getParameter("id");
if (hasLength(id)) {
Product p = productDao.get(Long.parseLong(id));
if (p != null)
req.setAttribute("p", p);
List&Supplier& suppliers = supplierDao.getSimpleSupplier();
req.setAttribute("suppliers", suppliers);
//防止重复提交:
//在导向编辑页面时,向request和session域中添加uuid随机数
UUIDToken.getInstance().generateUUIDToken(req);
// 导向添加页面
req.getRequestDispatcher("/WEB-INF/views/demo/product/edit.jsp").forward(req, resp);
// 执行保存过程
else if ("save".equals(cmd)) {
String id = req.getParameter("id");
Product p = new Product();
if (hasLength(id)) {
p = productDao.get(Long.parseLong(id));
System.out.println(req.getParameter("supplier"));
setProperties(req, p);
//判断是否重复提交
if(!UUIDToken.getInstance().isRepeatSubmit(req)){
if (p.getId() != null) {
productDao.update(p);
productDao.save(p);
System.out.println("重复提交!");
resp.sendRedirect(req.getContextPath() + "/product");
if ("del".equals(cmd)) {
// 执行删除过程
String id = req.getParameter("id");
if (hasLength(id)) {
productDao.delete(Long.parseLong(id));
// 列出所有货品(除了转向添加/编辑页面,其他都要执行这句)
// List&Product& ps = dao.getAll();
// req.setAttribute("ps", ps);
// req.getRequestDispatcher("/WEB-INF/jsp/list.jsp")
// .forward(req, resp);
ProductQueryObject pqo = createQueryObject(req);
// 高级查询
PageResult&Product& ps = productDao.getByQuery(pqo);
req.setAttribute("page", ps);
List&Supplier& suppliers = supplierDao.getSimpleSupplier();
req.setAttribute("suppliers", suppliers);
req.setAttribute("qo",pqo);
req.getRequestDispatcher("/WEB-INF/views/demo/product/list.jsp")
.forward(req, resp);
* 创建高级查询对象
* @param req
private ProductQueryObject createQueryObject(HttpServletRequest req) {
ProductQueryObject pqo = new ProductQueryObject();
pqo.setName(req.getParameter("name"));
pqo.setSn(req.getParameter("sn"));
pqo.setBrand(req.getParameter("brand"));
String supplier = req.getParameter("supplier");
if(StringUtil.isNotBlank(supplier)){
pqo.setSupplier(Long.parseLong(supplier));
String salePrice1 = req.getParameter("salePrice1");
if (hasLength(salePrice1))
pqo.setSalePrice1(new BigDecimal(salePrice1));
String salePrice2 = req.getParameter("salePrice2");
if (hasLength(salePrice2))
pqo.setSalePrice2(new BigDecimal(salePrice2));
String costPrice1 = req.getParameter("costPrice1");
if (hasLength(costPrice1))
pqo.setCostPrice1(new BigDecimal(costPrice1));
String costPrice2 = req.getParameter("costPrice2");
if (hasLength(costPrice2))
pqo.setCostPrice2(new BigDecimal(costPrice2));
String currentPage = req.getParameter("currentPage");
if (hasLength(currentPage)) {
pqo.setCurrentPage(Integer.parseInt(currentPage));
* @param req
* @param p
private void setProperties(HttpServletRequest req, Product p) {
p.setName(req.getParameter("name"));
p.setSn(req.getParameter("sn"));
String supplier_id = req.getParameter("supplier");
if(StringUtil.isNotBlank(supplier_id)){
Supplier s = new Supplier();
s.setId(Long.parseLong(supplier_id));
p.setSupplier(s);
p.setBrand(req.getParameter("brand"));
p.setTypes(req.getParameter("types"));
p.setUnit(req.getParameter("unit"));
p.setSalePrice(new BigDecimal(req.getParameter("salePrice")));
p.setCostPrice(new BigDecimal(req.getParameter("costPrice")));
p.setCutoffPrice(new BigDecimal(req.getParameter("cutoffPrice")));
public void init() throws ServletException {
super.init();
productDao = (IProductDao) DaoFactory.getDao("productDao");
supplierDao = (ISupplierDao) DaoFactory.getDao("supplierDao");
} edit.jsp
&%@ page language="java" pageEncoding="utf-8"
contentType="text/ charset=utf-8" %&
&%@ taglib uri="/jsp/jstl/core" prefix="c" %&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
&title&编辑产品&/title&
&form name="form1" action="&%=request.getContextPath() %&/product?cmd=save" method="post" &
&input type="hidden" name="id" value="${p.id }"&
&input type="hidden" name="UUIDTOKEN_IN_REQUEST" value="${UUIDTOKEN_IN_REQUEST }"&
&input type="hidden" name="UUIDTOKEN_FORMID_IN_REQUEST" value="${UUIDTOKEN_FORMID_IN_REQUEST }"&
&table width="90%" border="0" align="center" cellpadding="4" cellspacing="2" class="gray-bd3-2"&
&td width="100" align="center" class="brightcyan-tb"&产品名称:&/td&
&td&&input name="name" type="text" class="big-input" maxLength="20" size="20" value="${p.name }"/&&/td&
&td width="100" align="center" class="brightcyan-tb"&产品编码:&/td&
&td&&input name="sn" type="text" class="big-input" maxLength="20" size="20" value="${p.sn }"/&&/td&
&td width="100" align="center" class="brightcyan-tb"&供应商:&/td&
&select name="supplier"&
&option value="0"&--请选择--&/option&
&c:forEach var="o" items="${suppliers }"&
&option value="${o.id }" &c:if test="${not empty id && p.supplier.id == o.id }"&selected="selected"&/c:if&&
${o.name }
&/c:forEach&
&!-- &input name="supplier" type="text" class="big-input" maxLength="20" size="20" value="${p.supplier }"/& --&
&td width="100" align="center" class="brightcyan-tb"&品牌:&/td&
&td&&input name="brand" type="text" class="big-input" maxLength="20" size="20" value="${p.brand }"/&&/td&
&td width="100" align="center" class="brightcyan-tb"&分类:&/td&
&td&&input name="types" type="text" class="big-input" maxLength="20" size="20" value="${p.types }"/&&/td&
&td width="100" align="center" class="brightcyan-tb"&单位:&/td&
&td&&input name="unit" type="text" class="big-input" maxLength="20" size="20" value="${p.unit }"/&&/td&
&td width="100" align="center" class="brightcyan-tb"&零售价:&/td&
&td&&input name="salePrice" type="text" class="big-input" maxLength="20" size="20" value="${p.salePrice }"/&&/td&
&td width="100" align="center" class="brightcyan-tb"&成本价:&/td&
&td&&input name="costPrice" type="text" class="big-input" maxLength="20" size="20" value="${p.costPrice }"/&&/td&
&td width="100" align="center" class="brightcyan-tb"&折扣价:&/td&
&td&&input name="cutoffPrice" type="text" class="big-input" maxLength="20" size="20" value="${p.cutoffPrice }"/&&/td&
&p align="center"&
&input name="ok" type="button" class="small-btn" value="提交" onClick="save()"/&
&input type="reset" class="small-btn" value="重置" /&
&script type="text/javascript"&
function save(){
//forms javaScrip的内置对象 表示form的集合 是一个数组
//提交表单
document.forms[0].submit();
3. struts的同步令牌
利用同步令牌(Token)机制来解决Web应用中重复提交的问题,Struts也给出了一个参考实现。
基本原理:
服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,
看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给
客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次
提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
更多开发者职位上
1)">1)">1" ng-class="{current:{{currentPage==page}}}" ng-repeat="page in pages"><li class='page' ng-if="(endIndex<li class='page next' ng-if="(currentPage
相关文章阅读基于JavaWeb技术的表单重复提交问题解决方案分析与应用_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
您可以上传图片描述问题
联系电话:
请填写真实有效的信息,以便工作人员联系您,我们为您严格保密。
基于JavaWeb技术的表单重复提交问题解决方案分析与应用
||暂无简介
北京龙源网通电子商务有限公司|
总评分0.0|
试读已结束,如果需要继续阅读或下载,敬请购买
你可能喜欢用Struts的Token机制解决表单重复提交
用Struts的Token机制解决表单重复提交
  Struts的Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。    这时其实也就是两点,第一:你需要在请求中有这个令牌值,请求中的令牌值如何保存,其实就和我们平时在页面中保存一些信息是一样的,通过隐藏字段来保存,保存的形式如: 〈input type="hidden" name="org.apacl.TOKEN" value="6aafd996c4cae"〉,这个value是TokenProcessor类中的generateToken()获得的,是根据当前用户的session id和当前时间的long值来计算的。第二:在客户端提交后,我们要根据判断在请求中包含的值是否和服务器的令牌一致,因为服务器每次提交都会生成新的Token,所以,如果是重复提交,客户端的Token值和服务器端的Token值就会不一致。下面就以在数据库中插入一条数据来说明如何防止重复提交。    在Action中的add方法中,我们需要将Token值明确的要求保存在页面中,只需增加一条语句:saveToken(request);,如下所示:    public ActionForward add(ActionMapping mapping, ActionForm form,    HttpServletRequest request, HttpServletResponse response)    //前面的处理省略    saveToken(request);    return mapping.findForward("add");    }在Action的insert方法中,我们根据表单中的Token值与服务器端的Token值比较,如下所示:    public ActionForward insert(ActionMapping mapping, ActionForm form,    HttpServletRequest request, HttpServletResponse response)    if (isTokenValid(request, true)) {    // 表单不是重复提交    //这里是保存数据的代码    } else {    //表单重复提交    saveToken(request);    //其它的处理代码    }    }    其实使用起来很简单,举个最简单、最需要使用这个的例子:    一般控制重复提交主要是用在对数据库操作的控制上,比如插入、更新、删除等,由于更新、删除一般都是通过id来操作(例如:updateXXXById, removeXXXById),所以这类操作控制的意义不是很大(不排除个别现象),重复提交的控制也就主要是在插入时的控制了。    先说一下,我们目前所做项目的情况:    目前的项目是用Struts+Spring+Ibatis,页面用jstl,Struts复杂View层,Spring在Service层提供事务控制,Ibatis是用来代替JDBC,所有页面的访问都不是直接访问jsp,而是访问Structs的Action,再由Action来Forward到一个Jsp,所有针对数据库的操作,比如取数据或修改数据,都是在Action里面完成,所有的Action一般都继承BaseDispatchAction,这个是自己建立的类,目的是为所有的Action做一些统一的控制,在Struts层,对于一个功能,我们一般分为两个Action,一个Action里的功能是不需要调用Struts的验证功能的(常见的方法名称有add,edit,remove,view,list),另一个是需要调用Struts的验证功能的(常见的方法名称有insert,update)。    就拿论坛发贴来说吧,论坛发贴首先需要跳转到一个页面,你可以填写帖子的主题和内容,填写完后,单击“提交”,贴子就发表了,所以这里经过两个步骤:    1、转到一个新增的页面,在Action里我们一般称为add,例如:    public ActionForward add(ActionMapping mapping, ActionForm form,    HttpServletRequest request, HttpServletResponse response)    throws Exception {    //这一句是输出调试信息,表示代码执行到这一段了    log.debug(":: action - subject add");    //your code here    //这里保存Token值    saveToken(request);    //跳转到add页面,在Structs-config.xml里面定义,例如,跳转到subjectAdd.jsp    return mapping.findForward("add");    }    2、在填写标题和内容后,选择 提交 ,会提交到insert方法,在insert方法里判断,是否重复提交了。    public ActionForward insert(ActionMapping mapping, ActionForm form,    HttpServletRequest request, HttpServletResponse response){    if (isTokenValid(request, true)) {    // 表单不是重复提交    //这里是保存数据的代码    } else {    //表单重复提交    saveToken(request);    //其它的处理代码    }    }    下面更详细一点(注意,下面所有的代码使用全角括号):    1、你想发贴时,点击“我要发贴”链接的代码可以里这样的:    〈html:link action="subject.do?method=add"〉我要发贴〈/html:link〉    subject.do 和 method 这些在struct-config.xml如何定义我就不说了,点击链接后,会执行subject.do的add方法,代码如上面说的,跳转到subjectAdd.jsp页面。页面的代码大概如下:    〈html:form action="subjectForm.do?method=insert"〉    〈html:text property="title" /〉    〈html:textarea property="content" /〉    〈html:submit property="发表" /〉    〈html:reset property="重填" /〉    〈html:form〉    如果你在add方法里加了“saveToken(request);”这一句,那在subjectAdd.jsp生成的页面上,会多一个隐藏字段,类似于这样〈input type="hidden" name="org.apacl.TOKEN" value="6aafd996c4cae"〉,    2、点击发表后,表单提交到subjectForm.do里的insert方法后,你在insert方法里要将表单的数据插入到数据库中,如果没有进行重复提交的控制,那么每点击一次浏览器的刷新按钮,都会在数据库中插入一条相同的记录,增加下面的代码,你就可以控制用户的重复提交了。    if (isTokenValid(request, true)) {    // 表单不是重复提交    //这里是保存数据的代码    } else {    //表单重复提交    saveToken(request);    //其它的处理代码    }    注意,你必须在add方法里使用了saveToken(request),你才能在insert里判断,否则,你每次保存操作都是重复提交。    记住一点,Struts在你每次访问Action的时候,都会产生一个令牌,保存在你的Session里面,如果你在Action里的函数里面,使用了saveToken(request);,那么这个令牌也会保存在这个Action所Forward到的jsp所生成的静态页面里。    如果你在你Action的方法里使用了isTokenValid,那么Struts会将你从你的request里面去获取这个令牌值,然后和Session里的令牌值做比较,如果两者相等,就不是重复提交,如果不相等,就是重复提交了。    由于我们项目的所有Action都是继承自BaseDispatchAction这个类,所以我们基本上都是在这个类里面做了表单重复提交的控制,默认是控制add方法和insert方法,如果需要控制其它的方法,就自己手动写上面这些代码,否则是不需要手写的,控制的代码如下:    public abstract class BaseDispatchAction extends BaseAction {    protected ActionForward perform(ActionMapping mapping, ActionForm form,    HttpServletRequest request, HttpServletResponse response)    throws Exception {    String parameter = mapping.getParameter();    String name = request.getParameter(parameter);    if (null == name) { //如果没有指定 method ,则默认为 list    name = "list";    }    if ("add".equals(name)) {    if ("add".equals(name)) {    saveToken(request);    }    } else if ("insert".equals(name)) {    if (!isTokenValid(request, true)) {    resetToken(request);    saveError(request, new ActionMessage("error.repeatSubmit"));    log.error("重复提交!");    return mapping.findForward("error");    }    }    return dispatchMethod2(mapping, form, request, response, name);    }    }
&&&主编推荐
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
港口与航道工程建设工程法规及相关知识建设工程经济考试大纲矿业工程市政公用工程通信与广电工程
操作系统汇编语言计算机系统结构人工智能数据库系统微机与接口
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
Powerpoint教程WPS教程
电子政务客户关系管理首席信息官办公自动化大数据
职称考试题目
就业指导签约违约职业测评
招生信息考研政治
网络安全安全设置工具使用手机安全
3DMax教程Flash教程CorelDraw教程Director教程
Dreamwaver教程HTML教程网站策划网站运营Frontpage教程
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
互联网电信IT业界IT生活
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
组织运营财务资本
视频播放文件压缩杀毒软件输入法微博
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&}

我要回帖

更多关于 防止刷新重复提交post 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信