struts2.0 前台刷新重复提交

我用的是java中的struts2.0 spring hibernate;前台jsp页面每次刷新,都有重复提交;我提交按钮用的是submit

参考答案:我是copy过来的= =

1、 通过重定向的方式:把地址栏的地址显示为最后的地址。
2、 禁止客户端刷新:通过JS来控制,禁用刷新的功能、清除访问历史纪录;
3、 Struts自带的方式(令牌):服务器端发放一次性使用的令牌方式,服务器端给客户端每次请求发一个令牌,在客户端提交之后,检查令牌,如果这个令牌是第一次使用,就ok;否则,提示重复提交。
Action中有个几个相关方法:
SaveToken(request):生成一个新的令牌,并保存到客户端的请求对象中。
IsTokenValid(request,true):检查客户端的令牌是否是第一次使用,并且使该令牌失效。
ResetToken(request):重置客户端的令牌。用token令牌控制最有效了,你搜索一下token令牌,很多相关介绍

回复:这是转了别人的东西,我觉得挺实用的,就转过来给你了,如果你仔细理解意思,就能解决问题了,其实是个很简单的东西。 Struts的Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。 这时其实也就是两点,

第一:你需要在请求中有这个令牌值,请求中的令牌值如何保存,其实就和我们平时在页面中保存一些信息是一样的,通过隐藏字段来保存,保存的形式如:

〈input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"〉

这个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); //其它的处理代码 } } 下面更详细一点(注意,下面所有的代码使用全角括号):

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值