利用struts的token机制来解决重复提交
来源:互联网 发布:java私塾架构师实战三 编辑:程序博客网 时间:2024/05/19 13:58
重复提交问题在web开发中总会遇到,他主要发生在对数据库进行插入操作时。主要分为两种,一种是点击浏览器的刷新页面的重复提交,另一种是后退到上一页面,然后重新点击提交的重复提交。无论上面的哪一种,struts的token机制都能够很好的解决。
其基本原理是:服务器端在处理到达的请求之前,会将请求中包含的token值与保存在当前用户会话中的token值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的token,该token除传给客户端以外,也会将用户会话中保存的旧的token进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的token就和服务器端的token不一致,从而有效地防止了重复提交的发生。
下面给出一个简单例子,该例子中只对数据库进行模拟操作,主要是在Struts端进行讲解。
1. 在MyEclipse中创建一个名为struts的工程,导入struts1.x包。
2. 创建3个jsp页面——index.jsp,success.jsp,add.jsp,failure.jsp。其中index.jsp可以利用工程自带的,只需将其修改为:
<%@ page language="java" pageEncoding="utf-8" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.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="Thisis my page">
</head>
<body>
<a href ="toAdd.do">添加</a>
</body>
</html>
add.jsp的页面代码为,这个页面有一点很重要,就是form标签,一定要使用struts的form标签,如果不使用<html:form>,而是使用html自己的<form>,就不能够正常添加token,因为token只对struts的html标签支持,所以如题称为struts的token机制,其他标签可以不适用struts的标签:
-----------------------------------------------------------------------------------------------------------------
<%@ page language="java" pageEncoding="utf-8" %>
<%@ taglib uri="http://struts.apache.org/tags-bean"prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html"prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic"prefix="logic" %>
<%@ taglib uri="http://struts.apache.org/tags-tiles"prefix="tiles" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN">
<html:html >
<head>
<title>add.jsp</title>
</head>
<body>
<html:form action="/add">
<input type="text" id="username"name="username"/><br>
<input type="password" id="password"/ name="password"><br>
<input type="submit" value="提交" >
</html:form>
</body>
</html:html>
-----------------------------------------------------------------
接下来分别是success.jsp和failure.jsp的页面代码,其实都很简单,但是为了完整吧,写出来了:
---------------------------------------------------------------------------------------------------------
<%@ page language="java" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN">
<html>
<head>
<title>success.jsp</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="Thisis my page">
</head>
<body>
添加成功!!<br>
<a href ="toAdd.do">继续添加</a>
</body>
</html >
----------------------------------------------------------------
<%@ page language="java" pageEncoding="utf-8" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN">
<html>
<head>
<title>failure.jsp</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="Thisis my page">
</head>
<body>
添加失败!!!你是不是重复提交啦?
</body>
</html>
--------------------------------------------------------------------------------------------------------------
3. 然后是添加2个action——ToAddAction.java,AddAction.java
--------------------------------------------------------------------------------------------------------------------
packagecom.yourcompany.struts.action;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.apache.struts.action.Action;
importorg.apache.struts.action.ActionForm;
importorg.apache.struts.action.ActionForward;
importorg.apache.struts.action.ActionMapping;
public classToAddAction extends Action {
public ActionForward execute(ActionMappingmapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
saveToken(request);//此处进行保存,即可在下一页面add.jsp中传送token值
System.out.println();
returnmapping.findForward("add");
}
}
---------------------------------------------------------------------------------------------------------------------
packagecom.yourcompany.struts.action;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.apache.struts.action.Action;
importorg.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
importorg.apache.struts.action.ActionMapping;
importorg.apache.struts.action.ActionMessage;
importorg.apache.struts.action.ActionMessages;
importcom.lc.sqlhelp.Access;
importcom.yourcompany.struts.form.AddForm;
public classAddAction extends Action {
public ActionForward execute(ActionMappingmapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
AddForm af = (AddForm) form;
if (isTokenValid(request, true)) {
String sql = "insert into user(username,password) values('"
+ af.getUsername() + "','" + af.getPassword() +"')";
System.out.println(sql);
return mapping.findForward("add_suc");
}
saveToken(request);
return mapping.findForward("add_fail");
}
}
---------------------------------------------------------------------------------------------------------------------
4. 还有对应的formAction——AddForm.java
packagecom.yourcompany.struts.form;
importjavax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
importorg.apache.struts.action.ActionForm;
importorg.apache.struts.action.ActionMapping;
public classAddForm extends ActionForm {
/** password property */
private String password;
/** username property */
private String username;
/*
* Generated Methods
*/
public ActionErrors validate(ActionMappingmapping,
HttpServletRequest request) {
// TODO Auto-generated method stub
return null;
}
public void reset(ActionMapping mapping,HttpServletRequest request) {
// TODO Auto-generated method stub
}
/**
* Returns the password.
* @return String
*/
public String getPassword() {
return password;
}
/**
*Set the password.
* @param password The password to set
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Returns the username.
* @return String
*/
public String getUsername() {
return username;
}
/**
* Set the username.
* @param username The username to set
*/
public void setUsername(String username) {
this.username = username;
}
}
5. 然后是struts-config.xml,要注意struts的版本,我用的是struts1.2:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTDStruts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans >
<form-bean name="addForm"type="com.yourcompany.struts.form.AddForm"/>
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings >
<action
path="/toAdd"
type="com.yourcompany.struts.action.ToAddAction">
<forward name="add" path="/add.jsp" />
</action>
<action
attribute="addForm"
input="/add.jsp"
name="addForm"
path="/add"
scope="request"
type="com.yourcompany.struts.action.AddAction">
<forward name="add_suc"path="/success.jsp" />
<forward name="add_fail"path="/failure.jsp" />
</action>
</action-mappings>
<message-resources parameter="com.yourcompany.struts.ApplicationResources"/>
</struts-config>
6. 最后部署到tomcat中,运行程序http://localhost:8080/struts,,点击添加链接,即可进入http://localhost:8080/struts/toAdd.do,如果你在IE浏览器或者Firefox中进行测试的话,此时查看当前页面源代码,会发现其中body中的代码如下:
<body>
<form name="addForm" method="post" action="/struts/add.do"><div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="3934d9a3c0dcc57574411d5095649909"></div>
<input type="text" id="username" name="username"/><br>
<input type="password" id="password"/ name="password"><br>
<input type="submit" value="提交">
</form>
</body>
其中,form中多了一句隐藏,<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="3934d9a3c0dcc57574411d5095649909">,这个就是在saveToken(request)之后的结果,如果没有这句话,就不会产生这个隐藏的token,这样再add.do中才能够对token的值进行比较,判断是否重复提交。
7. 添加信息后,点击浏览器的刷新按钮或者后退到添加信息页面进行再次提交,都会进入failure.jsp页面,重复提交解决。
- 利用struts的token机制来解决重复提交
- 利用struts的Token机制解决重复提交问题的分析
- 利用struts的Token机制解决重复提交问题的分析
- Struts-利用Token解决重复提交
- Struts -- Token机制(解决表单重复提交)
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 使用Struts的Token机制解决表单的重复提交
- 用Struts的Token机制解决表单重复提交
- 用Struts的Token机制解决表单重复提交
- 用Struts的Token机制解决表单重复提交
- 使用JDBC连接SQL Server 2000数据库实例讲解
- 在JSP中用JDBC连接SQL Server2000
- 参数编码规范 完全解决方案
- csdn blog
- 2009将如何?
- 利用struts的token机制来解决重复提交
- “天下第一比武大会”策划(一)
- 中国所有省份及地区
- 亲爱的朋友,欢迎入住网易博客家园
- linux下firefox的视频插件
- 如何在Android Market赚钱 part 2 - 免费app附带广告(转)
- oracle连接数据库测试代码
- 通过JDBC连接oracle数据库的十大技巧
- 赛迪J2ME移动程序开发与实例初级班