フォームの繰り返しの提出:一度完了しません。最初にフォームページをリクエストしてから、フォームプロセスを送信してデータ送信を完了します
根本原因:それを完全に行わない、最初にフォームページ - >フォームプロセスを送信します。
繰り返しの提出物を引き起こします:
注:倒れた後、フォームページを更新して再度送信します。この時点で、提出物を繰り返す代わりに、新しいリクエストが送信されます。 Firefoxでは、同じアドレスへの提出を繰り返す動作が無効です。
場合:
@webservlet( "/trans")public class transferServletはhttpservletを拡張します{private static final long serialversionuid = 1l;保護されたvoidサービス(httpservletrequest req、httpservletresponse rep)servletexception、ioexception {req.setcharacterencoding( "utf-8"); resp.setContentType( "text/html; charset = utf-8"); printwriter out = resp.getWriter(); string money = req.getParameter( "Money"); //ネットワーク遅延をシミュレートしてみてください{thread.sleep(3000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "転送された金額:"+money); out.print( "転送された金額:"+money); }}クレイジーなポイントの下では、JSPページは変更されないことがわかりますが、バックグラウンドでの印刷を介して見ることができ、継続的に出力され、常に実行されていることを示しています。
解決:
保証を送信する前に、最初にフォームインターフェイスを要求する必要があります。原則は検証コードと同じです。---トークンメカニズム
初めて要求するとき、フォームインターフェイスにリクエストするときは、トークンを作成します。転送をクリックしてリクエストを送信するときは、このトークンを持参して、次のインターフェイスに送信します。サーブレットのトークンを確認します。このトークンはセッションに1つ、フォームの1つです。イコライゼーションとは、フォームが正しいことを意味し、このセッションのトークンが破壊されます。
JSPページのコード
<%// token string token = java.util.uuid.randomuid()。toString(); //セッションの1つが存在し、次に判断session.setattribute( "token_in_session"、token)を作成します。 %転送インターフェイス</h3> <form action = "/trans" method = "post"> <入力タイプ= "hidden" name = "token" value = "<%= token%>"/>転送金額:<入力タイプ= "テキスト"名= "
TransferServletのコード
@webservlet( "/trans")public class transferServletはhttpservletを拡張します{private static final long serialversionuid = 1l;保護されたvoidサービス(httpservletrequest req、httpservletresponse rep)servletexception、ioexception {req.setcharacterencoding( "utf-8"); resp.setContentType( "text/html; charset = utf-8"); printwriter out = resp.getWriter(); // string token = req.getParameter( "token")の形式でトークン値を取得します。 //セッション文字列sessiontoken =(string)req.getSession()。getAttribute( "token_in_session");でトークン値を取得します。 //セッションのトークンは、セッションのトークンが(token.equals(sessiontoken)))場合に破壊可能なため空になりやすいです。//トークンは同じreq.getSession()。 string money = req.getParameter( "Money"); System.out.println( "転送金額:"+マネー); out.print( "転送金額:"+money); //最後にセッションでトークンを破壊します} //トークンが異なる場合、それは繰り返される提出であり、提出できないことを意味します}}}次に、JSPファイルのJavaコードに表示されないように、別のサーブレットでトークンを作成してジャンプします
@webservlet( "/transfer")public class copyofoftransferservletはhttpservletを拡張します{private static final long serialversionuid = 1l;保護されたボイドサービス(httpservletrequest req、httpservletresponse rep)servletexception、ioexception {// tokenを作成してsubmit.jsp string token = uuid.randomuid()。toString(); System.out.println(token); req.getSession()。setAttribute( "token_in_session"、token); req.setattribute( "token"、token); req.getRequestDispatcher( "/views/Repeatsubmit/submit.jsp")。 }}これはJSPファイルが現在どのように見えるかです
<h3> transfer interface </h3> <form action = "/trans" method = "post"> <入力タイプ= "hidden" name = "token" value = "$ {token}"/>転送金額:<入力タイプ= "テキスト" name = "min =" "min =" 1 "必須/> <br/> <入力タイプ=" "submit" "froms"/>> </>> </>> <上記よりもはるかにきれいできれいですが、他の場所でそれを使用する必要がある場合は、トークンを作成し、トークンを検証し、トークンを削除する必要があるため、ツールクラスを作成するためにトークンを削除する必要があるため、気分が良くありません。
tokenutil.java
//トークンツールクラス//トークンを作成//トークンを検証//トークンパブリッククラスtokenutil {private final static string token_in_session = "token_in_session"; public static void savatoken(httpservletrequest req){string token = uuid.randomuuid()。toString(); System.out.println(token); req.getSession()。setAttribute(token_in_session、token); req.setattribute( "token"、token); } public static boolean balidateToken(httpservletrequest req、string tokeninrequest){//セッションでトークン値を取得=(string)req.getSession()。 if(tokeninrequest.equals(sessiontoken)){req.getSession()。removeattribute(token_in_session); trueを返します。 } falseを返します。 }}これで問題ありません。ユーザーはこのツールクラスを呼び出すだけで、トークンの作成などの一連の操作を作成する必要はありません。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。