利用struts的token机制来解决重复提交

1 篇文章 0 订阅
0 篇文章 0 订阅

 

 

 

 

 

重复提交问题在web开发中总会遇到,他主要发生在对数据库进行插入操作时。主要分为两种,一种是点击浏览器的刷新页面的重复提交,另一种是后退到上一页面,然后重新点击提交的重复提交。无论上面的哪一种,strutstoken机制都能够很好的解决。

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

       下面给出一个简单例子,该例子中只对数据库进行模拟操作,主要是在Struts端进行讲解。

1.       MyEclipse中创建一个名为struts的工程,导入struts1.x包。


2.       创建3jsp页面——index.jspsuccess.jspadd.jspfailure.jsp。其中index.jsp可以利用工程自带的,只需将其修改为:

<%@ page language="java" pageEncoding="utf-8" %>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 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="This is my page">

   

  </head>

 

  <body>

    <a href ="toAdd.do">添加</a>

  </body>

</html>

 

add.jsp的页面代码为,这个页面有一点很重要,就是form标签,一定要使用strutsform标签,如果不使用<html:form>,而是使用html自己的<form>,就不能够正常添加token,因为token只对strutshtml标签支持,所以如题称为strutstoken机制,其他标签可以不适用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//DTD HTML 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.jspfailure.jsp的页面代码,其实都很简单,但是为了完整吧,写出来了:

---------------------------------------------------------------------------------------------------------

<%@ page language="java" pageEncoding="utf-8"%>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 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="This is my page">

 

  </head>

 

  <body>

添加成功!!<br>

<a href ="toAdd.do">继续添加</a>

  </body>

</html >

----------------------------------------------------------------

<%@ page language="java" pageEncoding="utf-8" %>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 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="This is my page">

 

  </head>

 

  <body>

添加失败!!!你是不是重复提交啦?

  </body>

</html>

--------------------------------------------------------------------------------------------------------------

3.       然后是添加2action——ToAddAction.javaAddAction.java

--------------------------------------------------------------------------------------------------------------------

package com.yourcompany.struts.action;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

 

public class ToAddAction extends Action {

   

    public ActionForward execute(ActionMapping mapping, ActionForm form,

           HttpServletRequest request, HttpServletResponse response) {

           saveToken(request);//此处进行保存,即可在下一页面add.jsp中传送token

           System.out.println();

              return mapping.findForward("add");

    }

}

---------------------------------------------------------------------------------------------------------------------

package com.yourcompany.struts.action;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

import org.apache.struts.action.ActionMessage;

import org.apache.struts.action.ActionMessages;

 

import com.lc.sqlhelp.Access;

import com.yourcompany.struts.form.AddForm;

 

public class AddAction extends Action {

   

    public ActionForward execute(ActionMapping mapping, 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

 

package com.yourcompany.struts.form;

 

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionErrors;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionMapping;

 

public class AddForm extends ActionForm {

  

    /** password property */

    private String password;

 

    /** username property */

    private String username;

 

    /*

     * Generated Methods

     */

 

   

    public ActionErrors validate(ActionMapping mapping,

           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//DTD Struts 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页面,重复提交解决。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值