适用场景:在从页面向数据库中插入数据时,比如用户注册,提交留言等,当操作成功之后,再点击“后退”按钮,退回到表单页再次提交表
单,如果对此重复提交未加处理,将会再次提交成功,数据库中就会有重复的数据,这种情况是不合理的。
Struts解决方案:Struts框架的令牌机制(TOKEN)很好的解决了这个表单重复提交的问题。
基本原理:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
下面通过一个例子来说明:
例子操作内容:通过留言板向数据库中插入一条留言记录。
文件包括:
messageAdd.jsp
messageSubmit.jsp
messageError.jsp
messageSuccess.jsp
messageAction.java
messageForm.java
struts-config.xml
messageAdd.jsp
<%@ page language="java" pageEncoding="gbk"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<%@include file="/header.jsp" %>
<title>防止重复提交</title>
</head>
<body>
<a href="<%=basePath%>strutsTest.do?method=add">我要留言</a>
</body>
</html>
messageSubmit.jsp
<%@ page language="java" pageEncoding="gbk"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<%@include file="/header.jsp"%>
<title>add.jsp</title>
</head>
<body>
<html:form. action="strutsTest.do?method=insert" method="post" >
<table>
<tr>
<td>
留言
</td>
</tr>
<tr>
<td>
<textarea id="content" name="content"></textarea>
</td>
</tr>
<tr>
<td>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</td>
</tr>
</table>
</html:form>
</body>
</html>
messageError.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>错误页面</title>
</head>
<body>
请不要重复提交
</body>
</html>
messageSuccess.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>成功页面</title>
</head>
<body>
留言成功
</body>
</html>
MessageAction.java
public class MessageAction extends DispatchAction
{
public ActionForward add(ActionMapping mapping, ActionForm. form, HttpServletRequest request, HttpServletResponseresponse)
{
TokenProcessor processor=TokenProcessor.getInstance();
processor.saveToken(request);
return mapping.findForward("add");
}
public ActionForward insert(ActionMapping mapping, ActionForm. form, HttpServletRequest request, HttpServletResponseresponse)
{
MessageForm.strutsForm=(MessageForm)form;
String message=strutsForm.getContent();
TokenProcessor processor=TokenProcessor.getInstance();
String tour1="error";
if(message!=null&&!"".equals(message))
{
if(processor.isTokenValid(request,true))
{
tour1="success";
}
else
{
processor.saveToken(request);
}
}
return mapping.findForward(tour1);
}
}
MessageForm.java
public class MessageForm. extends ActionForm
{
private static final long serialVersionUID =1L;
private String content="";
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content = content;
}
}
struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN""http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans >
<form-bean name="messForm"
type="com.xinglongjian.struts.action.MessageForm" />
</form-beans>
<global-exceptions />
<action-mappings>
<action path="/strutsTest" parameter="method" name="messForm"
type="com.xinglongjian.struts.action.MessageAction" >
<forward name="add" path="/struts/messageSubmit.jsp"></forward>
<forward name="error" path="/struts/messageError.jsp"></forward>
<forward name="success" path="/struts/messageSuccess.jsp"></forward>
</action>
</action-mappings>
</struts-config>
注意事项:
1 TokenProcessor类,这个类是对Token进行操作的。可以查看源代码弄明白saveToken(request),isTokenValid(request,true)等方法的具体实现。
从代码中可以看出,token值是由用户的Session ID和当前时间算出来的,并将其放入session中,key为Globals.TRANSACTION_TOKEN_KEY
2,页面中form标签要用struts的标签<html:form>原因是:因为当应用服务器初始化填写表单页面遇到标签<html:form>时,便会调用struts的FormTag类的renderToken()方法。该方法会当检测到session中的Globals.TRANSACTION_TOKEN_KEY不为空时,在填写表单页面创建元素:
<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="">,
名称为:org.apache.struts.taglib.html.TOKEN就是Constants.TOKEN_KEY;
值为:session中的Globals.TRANSACTION_TOKEN_KEY的值.
另外必须在struts-config.xml中配置form-bean,而且name属性值要与action的name属性值一致,因为struts的form标签与一个Form对象对应。
<!----------------做个小记录...-------------->
分享到:
相关推荐
Struts2作为一个流行的Java Web框架,为解决表单重复提交提供了多种方法。 首先,关于表单重复提交的原因,有以下几点: 1. 服务器或网络延迟导致用户多次点击提交按钮。 2. 用户在表单提交后刷新浏览器页面。 ...
总的来说,Struts2的`token`拦截器是防止重复提交的有效解决方案,通过结合合理的拦截器配置和跳转策略,可以确保应用程序的稳定性和数据一致性。在实际开发中,还需要考虑其他因素,如异常处理、用户体验优化等,以...
"防止表单重复提交 token"是Struts2提供的一种解决方案,通过在请求中加入一个唯一的token来确保请求的唯一性和一致性。 首先,我们来看如何实现这个机制。在Struts2中,我们可以使用拦截器(Interceptor)来实现...
在Web开发中,表单重复提交是一个常见的问题,它可能导致数据的不一致性或者服务端处理逻辑的混乱。Struts2框架提供了一种解决方案,即使用Token机制来防止表单的重复提交。以下是对这个主题的详细说明: 1. **表单...
总的来说,Struts Token机制通过维护一个临时的、一次性使用的Token,有效地解决了Web应用中的表单重复提交问题,提高了系统的稳定性和安全性。在实际开发中,应根据项目需求灵活运用并优化此机制。
struts2防止表单重复提交,利用struts的拦截器tokenSession,轻轻松松解决表单重复提交的问题。 附件为源代码,后台延迟了3秒,可直接在web服务器下部署运行,输入用户名和密码后,多点几次提交按钮,然后看控制台...
在提供的压缩包文件"struts+token机制解决表单重复提交"中,可能包含了具体的Struts配置文件、Action类、Interceptor实现以及示例代码,可以帮助读者更深入地理解并实践这个机制。通过对这些代码的学习和研究,...
综上所述,Struts框架通过Token机制有效地解决了表单重复提交的问题,提供了更健壮的Web应用安全性。正确理解和应用这一机制对于Java Web开发者来说至关重要。在实际项目中,结合其他防御策略,如CSRF防护,可以...
下面将详细讲解Struts2令牌解决重复提交问题的过程: 1. **生成令牌**:在Action中,使用`TokenAwareActionSupport`作为基类,这个类实现了`TokenSessionStore`接口,可以方便地获取和验证令牌。在表单展示之前,...
通过以上步骤,我们可以有效地利用Struts框架内置的令牌机制来解决表单重复提交的问题。这种方法简单易行,同时也能提高应用的安全性和用户体验。在实际项目中,可以根据具体需求灵活调整令牌的有效期、验证逻辑等,...
在处理用户表单提交时,Struts框架可能会遇到一个常见的问题,即表单重复提交。这种情况通常发生在用户点击提交按钮后,由于网络延迟或其他原因导致请求被多次发送,从而可能对服务器端造成多次数据插入或更新,导致...
在实际开发中,Struts框架的一个常见问题就是“重复提交”。本文将深入探讨这个问题,并提供解决方案。 一、什么是重复提交? 在Web应用中,用户可能会意外地多次点击提交按钮,导致服务器端接收到多个相同请求,这...
总结来说,Servlet、Struts和SpringMVC都提供了各自的解决方案来防止表单重复提交,主要方法包括使用Session、令牌机制、重定向和拦截器等。开发者可以根据项目需求选择合适的方式来实现,确保应用的稳定性和数据...
### 使用Struts Token机制解决表单重复提交 #### 一、引言 在Web应用程序开发过程中,表单重复提交是一个常见的问题。用户可能因为网络延迟、浏览器缓存等原因导致重复点击提交按钮,进而向服务器发送多个相同的...
下面将详细解释Struts2如何通过重定向来防止表单重复提交。 首先,理解表单重复提交的场景:用户在提交表单后,由于网络延迟或其他原因,可能会无意中多次点击提交按钮。如果服务器没有处理这些重复请求,那么相同...
Struts2是一个流行的Java ...总结来说,Struts2通过Token机制有效地解决了表单重复提交的问题,提高了Web应用的健壮性。通过合理的配置和拦截器的使用,开发者可以轻松地集成这一功能,确保每个表单请求只被处理一次。
综上所述,Struts2文件上传下载和表单重复提交涉及多个技术点,包括Struts2的配置、文件操作、HTTP响应头设置、安全性和异常处理。理解并熟练掌握这些知识点,对于构建健壮的Web应用程序至关重要。