struts 1.xフォームの重複コミットの問題の解決

6337 ワード

フォームの記入が完了するたびに「発行」をクリックすると、strutsでactionが関連するビジネスロジックを実行し、forwardオブジェクトを介してページに移動します.このときページをリフレッシュすると、同じ論理が実行されます.たとえば、データベースにデータを記録すると、上記の場合、データベースに同じデータが2つあります.このような状況を回避するために、いくつかの解決策があります:1:ビジネスロジックを実行した後、1つのForwardオブジェクトを返します.このforwardオブジェクトのpath属性はべき乗などのXXX.do操作を構成するべきで、このように解決することができますが、ユーザーの要求に合わない可能性がありますので、他の方法があります.2:リダイレクト、プロファイル内でredirectプロパティを構成し、xxx.jspにリダイレクトします.この場合request範囲内のパラメータが失われ、xxx.jspがこれらのパラメータを要求しなければ、操作したデータがsession範囲内に保存されていれば、全体の効果に影響しません.しかし、やはり弊害がある.3:struts 1.xトークンを使用すると、このような問題をうまく解決できます.必要条件:フォーム内でstrutsのライブラリラベル(次の例を示します.
LoginAction:
 package com.web.action;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.apache.struts.action.ActionForm;
 import org.apache.struts.action.ActionForward;
 import org.apache.struts.action.ActionMapping;
 import org.apache.struts.actions.DispatchAction;
 public class LoginAction extends DispatchAction  {
    public ActionForward get(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
           throws Exception  {
       //    (   jsp     32 jsessionid)\
        this.saveToken(request);
        System.out.println("begin save");
        return mapping.findForward("login");
    }
    
    public ActionForward login(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception  {
        /**//*if(this.isTokenValid(request))
        {
            System.out.println("valid");
            this.resetToken(request);
            return mapping.findForward("ok");
        }*/
        //               
        if(this.isTokenValid(request,true))
         {
            System.out.println("valid");
            return mapping.findForward("ok");
        }
        else
        {
            System.out.println("invalid");
            return mapping.findForward("error");
        }
    }
}
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="loginForm" type="com.web.form.LoginForm"></form-bean>
     </form-beans>
     <global-exceptions />
     <global-forwards />
     <action-mappings>
         <action path="/login" parameter="method" name="loginForm"
             type="com.web.action.LoginAction">
             <forward name="login" path="/login.jsp" />
             <forward name="ok" path="/ok.jsp" />
             <forward name="error" path="/error.jsp" />
         </action>
     </action-mappings>
     <message-resources parameter="" />
 </struts-config>
index.jsp:

<% @page contentType="text/html; charset=GBK"%>
<% @taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <c:set var="ctx" value="${pageContext.request.contextPath}" />
 <html>
   <head>
     <title>My Jsp</title>
   </head>
   <body>
   <a href="${ctx}/login.do?method=get">  </a>
   </body>
 </html>
login.jsp:

<% @page contentType="text/html; charset=GBK"%>
<% @taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<% @taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>
 <html>
   <head>
     <title>My Jsp</title>
   </head>
   <body>
   <c:set var="ctx" value="${pageContext.request.contextPath}"/>
   <!--       html  ,  token    -->
   <html:form action="login.do?method=login" method="post">
     <html:submit value="  "></html:submit>
   </html:form>
   </body>
 </html>
最初に実行すると、「成功」というメッセージが表示されます.
login.jspに戻ってソースコードを確認します.

<html>
   <head>
     <title>My Jsp</title>
   </head>
   <body>
   
   <form name="loginForm" method="post" action="/strutsToken/login.do?method=login">
 <div><input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="d7484f95247cf242a6f35107a1c7ac25"></div>
     <input type="submit" value="  ">
   </form>
   </body>
 </html>
私たちが書いたlogin.jspと比較すると、
32ビットの唯一のJsessionIDを値として生成します.LoginActionのgetメソッドのsaveToken(request)同じです.この文の役割はjsessionidをrequestの範囲に保存することです.私たちが後退して再呼び出します:if(this.isTokenValid(request,true))         {            System.out.println("valid");             return mapping.findForward("ok");         } すると、login.jspから送られてきたjsessionidとrequestを比較します.同じであれば、説明は合法ではありません.私たちの操作はすべて要求セッションで操作されているからです.繰り返し提出していることを説明します.異なる場合、説明は唯一のjsessionidを再生成しました(新しいブラウザを開きます)を開き、新しいセッションを開き、再送信するのが合法です.これによりフォームの重複送信の問題が防止されます.フォームの重複送信を防止するために、一般的にactionメソッドを設計する際に、データを入力するなど、2つのメソッド、add()とinsert()を設計し、addメソッドにトークンを保存してページに移動し、ページにinsertメソッドにコミットし、トークンを判断します.