导航:首页 > 编程语言 > java重复提交

java重复提交

发布时间:2025-05-02 09:04:59

Ⅰ 请教java 登录token的代码

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

这时其实也就是两点,第一:你需要在请求中有这个令牌值,请求中的令牌值如何保存,其实就和我们平时在页面中保存一些信息是一样的,通过隐藏字段来保存,保存的形式如: 〈input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value=""〉,这个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.apache.struts.taglib.html.TOKEN" value=""〉,

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);

}

}

Ⅱ java token有什么用

Struts本身有一套完善的防止重复提交表单的Token(令牌)机制,但笔者目前的项目自版写的framework没有用到权Struts,故也得自写防止用户因为后退或者刷新来重复提交表单内容的Token机制。不难,容易实现。

实现原理:一致性。jsp生成表单时,在表单中插入一个隐藏<input>字段,该字段就是保存在页面端的token字符串,同时把该字符串存入session中。等到用户提交表单时,会一并提交该隐藏的token字符串。在服务器端,查看下是否在session中含有与该token字符串相等的字符串。如果有,那么表明是第一次提交该表单,然后删除存放于session端的token字符串,再做正常业务逻辑流程;如果没有,那么表示该表单被重复提交,做非正常流程处理,可以警告提示也可以什么也不做。 网络的.

Ⅲ javaweb防止表单重复提交的几种解决方案

1.js方法解决:关于js方法解决就是说通过js动态控制提交按钮不能多次点击,或者多次点击不起作用。

方案一:通过设立标识使表单不能重复提交:

要强调的是,利用session方法解决表单重复问题是十分完美的,基本上可以应对各种重复提交问题。

但!是不是之前在客户端防止表单重复提交的种种方法就不使用了呢?

答案是否定的,我们需要多种方法混合使用才能达到最好的效果,也许有人会问,不是说session方法基本可以应对各种重复提交问题了吗?

这里我们所说的达到最好效果指的是,给用户更好地体验,例如用户点击了提交按钮,这时将按钮变为不可用的,用以告诉用户你已经提交内容了,不可重复提交。还有如果无论什么情况都用session防止表单重复提交问题,反而无形的增加了服务器端的负担。

Ⅳ java如何实现你提交太频繁了

可以使用前、后端分别拦截的方式。
前端拦截是指通过 HTML 页面来拦截重复请求,比如在用户点击完“提交”按钮后,我们可以把按钮设置为不可用或者隐藏状态。但前端拦截有一个致命的问题,如果是懂行的程序员或非法用户可以直接绕过前端页面,通过模拟请求来重复提交请求,比如充值了100元,重复提交了10次变成了1000元。所以除了前端拦截一部分正常的误操作之外,后端的拦截也是必不可少。后端拦截的实现思路是在方法执行之前,先判断此业务是否已经执行过,如果执行过则不再执行,否则就正常执行,将请求的业务 ID 存储在内存中,并且通过添加互斥锁来保证多线程下的程序执行安全。

阅读全文

与java重复提交相关的资料

热点内容
红米1s手机现在最新什么版本号 浏览:561
搭错车哪个版本好 浏览:892
微信保存文件后找不到 浏览:198
苹果屏蔽陌生号码来电 浏览:60
企业微信怎么放共享文件 浏览:234
公租房需要哪些文件 浏览:786
佰荣圈app是什么意思 浏览:559
wifi密码数据备份软件 浏览:221
qq欢乐积分商城等级 浏览:102
mayapainteffects教程 浏览:240
rayaapp 浏览:774
手机卡屏怎么修复工具 浏览:579
哪些属于数据备份常用方式 浏览:227
卖读物在哪个网站最好 浏览:135
手机里哪个软件适合编程 浏览:502
word文件如何调两边边距 浏览:754
会计规章和规范文件包括哪些 浏览:272
怎样复制显示一半的文件名 浏览:437
文明6快吧破解版启动文件在哪里 浏览:90
2017年苹果616g多少钱 浏览:315

友情链接