Pengajuan formulir yang diulang: Tidak lengkap sekali, pertama minta halaman formulir -> lalu kirimkan proses formulir untuk melengkapi pengiriman data
Akar Penyebab: Tidak melakukannya secara lengkap, pertama minta halaman formulir -> lalu kirimkan proses formulir.
Penyebab Pengajuan Berulang:
Catatan: Setelah jatuh kembali, segarkan halaman formulir dan kirim lagi. Pada saat ini, alih -alih mengulangi pengiriman, permintaan baru dikirim. Di bawah Firefox, pengoperasian pengulangan pengajuan ke alamat yang sama tidak valid.
Kasus:
@Webservlet ("/trans") TransferServlet kelas publik memperluas httpservlet {private static final long serialversionuid = 1l; Layanan void yang dilindungi (httpservletrequest req, httpservletresponse resp) melempar servletException, ioException {req.setcharacterencoding ("UTF-8"); resp.setContentType ("Teks/html; charset = utf-8"); Printwriter out = resp.getWriter (); String money = req.getParameter ("uang"); // simulasikan penundaan jaringan coba {thread.sleep (3000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("Jumlah yang ditransfer:"+uang); out.print ("Jumlah keluar yang ditransfer:"+uang); }}Di bawah titik gila, Anda akan menemukan bahwa halaman JSP tidak akan berubah, tetapi Anda dapat melihat melalui cetakan di latar belakang, dan itu akan output terus menerus, menunjukkan bahwa itu sedang dieksekusi sepanjang waktu
Larutan:
Sebelum mengirimkan jaminan, terlebih dahulu Anda harus meminta antarmuka formulir. Prinsipnya sama dengan kode verifikasi .---- Mekanisme token
Saat meminta pertama kali, saat meminta ke antarmuka formulir, buat token. Saat mengklik transfer dan mengirim permintaan, bawa token ini dan kirimkan ke antarmuka berikutnya. Verifikasi token di servlet. Token ini adalah satu di sesi dan satu dalam formulir. Penyamaan berarti bahwa formulir itu benar, dan token dalam sesi ini dihancurkan.
Kode di halaman JSP
<% // buat token string token = java.util.uuid.randomuuid (). Tostring (); // Salah satu sesi ada, dan kemudian membuat penilaian sesi.setAttribute ("token_in_session", token); %> <h3>Transfer interface</h3> <form action="/trans" method="post"> <input type="hidden" name="token" value="<%=token%>"/> Transfer amount:<input type="text" name="money" min="1" required /><br/> <input type="submit" value="transfer" /> </form>Kode dalam TransferServlet
@Webservlet ("/trans") TransferServlet kelas publik memperluas httpservlet {private static final long serialversionuid = 1l; Layanan void yang dilindungi (httpservletrequest req, httpservletresponse resp) melempar servletException, ioException {req.setcharacterencoding ("UTF-8"); resp.setContentType ("Teks/html; charset = utf-8"); Printwriter out = resp.getWriter (); // Dapatkan nilai token di Token String Form = req.getParameter ("token"); // Dapatkan nilai token di session string sessionToken = (string) req.getSession (). GetAttribute ("token_in_session"); // Token dalam sesi mudah dikosongkan karena token dalam sesi ini adalah if (token.equals (sessionToken)) {// menunjukkan bahwa token adalah req.getSession () yang sama (). RemoveAttribute ("token_in_session"); String money = req.getParameter ("uang"); System.out.println ("Jumlah Transfer:"+Uang); out.print ("Jumlah transfer:"+uang); // Akhirnya hancurkan token di sesi} // jika token berbeda, itu berarti bahwa itu adalah pengiriman berulang dan tidak dapat dikirim}}Kemudian, agar tidak muncul dalam kode Java di file JSP, buat dan lompat token di servlet lain
@Webservlet ("/transfer") kelas publik copyOfTransFerServlet memperluas httpservlet {private static final long serialversionuid = 1l; Layanan void yang dilindungi (httpservletRequest req, httpservletResponse resp) melempar servletException, ioException {// Buat token dan lompat untuk mengirimkan.jsp string token = uuid.randomuuid (). tostring (); System.out.println (token); req.getSession (). setAttribute ("token_in_session", token); req.setAttribute ("token", token); req.getRequestDispatcher ("/views/repeatsubmit/submit.jsp"). Forward (req, resp); }}Seperti inilah file JSP sekarang
<h3> Antarmuka transfer </h3> <form Action = "/trans" Method = "Post"> <input type = "hidden" name = "token" value = "$ {token}"/> Jumlah transfer: <input type = "Text" name = "Money" Min = "1" Diperlukan/> <br/> <input type = "Submit" Value "Value"Ini jauh lebih bersih daripada di atas dan lebih rapi, tetapi masih terasa tidak enak, karena jika Anda perlu menggunakannya di tempat lain, Anda perlu membuat token, memverifikasi token, dan menghapus token, jadi Anda mengekstraknya untuk membuat kelas alat
Tokenutil.java
// Token Tool Class // Buat token // Verifikasi token // Hancurkan Token Public Class 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 validateToken (httpservletrequest req, string tokeninRequest) {// Dapatkan nilai token di sessionstring sessionToken = (string) req.getSession (). getAttribute (token_in_session); if (tokeninRequest.equals (sessionToken)) {req.getSession (). RemoveAttribute (Token_in_Session); Kembali Benar; } return false; }}Ini baik -baik saja. Pengguna hanya perlu memanggil kelas alat ini, dan tidak perlu menulis serangkaian operasi seperti membuat token.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.