การส่งแบบฟอร์มซ้ำ ๆ : ไม่เสร็จสิ้นครั้งแรกขอหน้าแบบฟอร์มก่อน -> จากนั้นส่งกระบวนการฟอร์มเพื่อส่งข้อมูลให้เสร็จสิ้น
สาเหตุที่แท้จริง: ไม่ทำอย่างเต็มที่ให้ขอหน้าแบบฟอร์มก่อน -> จากนั้นส่งกระบวนการฟอร์ม
ทำให้เกิดการส่งซ้ำ:
หมายเหตุ: หลังจากถอยกลับให้รีเฟรชหน้าฟอร์มและส่งอีกครั้ง ในเวลานี้แทนที่จะส่งการส่งซ้ำคำขอใหม่จะถูกส่ง ภายใต้ Firefox การดำเนินการทำซ้ำการส่งไปยังที่อยู่เดียวกันนั้นไม่ถูกต้อง
กรณี:
@webservlet ("/trans") การถ่ายโอนระดับสาธารณะ Public Extion Httpservlet {ส่วนตัวคงที่สุดท้าย Long SerialVersionUID = 1L; บริการโมฆะที่ได้รับการป้องกัน (httpservletrequest REQ, httpservletResponse resp) พ่น servletexception, ioexception {req.setcharacterencoding ("UTF-8"); resp.setContentType ("ข้อความ/html; charset = utf-8"); PrintWriter out = resp.getWriter (); สตริงเงิน = req.getParameter ("เงิน"); // จำลองการหน่วงเวลาเครือข่ายลอง {thread.sleep (3000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("โอนเงินออก:"+เงิน); out.print ("โอนเงินออก:"+เงิน); -ภายใต้จุดที่บ้าคุณจะพบว่าหน้า JSP จะไม่เปลี่ยนแปลง แต่คุณสามารถดูผ่านการพิมพ์ในพื้นหลังและมันจะส่งออกอย่างต่อเนื่องแสดงให้เห็นว่ากำลังดำเนินการตลอดเวลา
สารละลาย:
ก่อนที่จะส่งการรับประกันคุณต้องขอแบบฟอร์มอินเทอร์เฟซก่อน หลักการเหมือนกับรหัสการตรวจสอบ .--- กลไกโทเค็น
เมื่อร้องขอครั้งแรกเมื่อร้องขอไปยังอินเทอร์เฟซแบบฟอร์มให้สร้างโทเค็น เมื่อคลิกที่การถ่ายโอนและส่งคำขอนำโทเค็นนี้และส่งไปยังอินเทอร์เฟซถัดไป ตรวจสอบโทเค็นใน servlet โทเค็นนี้เป็นหนึ่งในเซสชั่นและอีกหนึ่งในรูปแบบ การทำให้เท่าเทียมกันหมายความว่าแบบฟอร์มนั้นถูกต้องและโทเค็นในเซสชั่นนี้ถูกทำลาย
รหัสในหน้า JSP
<% // สร้างโทเค็นโทเค็น = java.util.uuid.randomuuid (). toString (); // หนึ่งในเซสชั่นมีอยู่แล้วทำการตัดสินเซสชัน SetAttribute ("TOKEN_IN_SESSION" โทเค็น); %> <h3> การถ่ายโอนอินเทอร์เฟซ </h3> <form action = "/trans" method = "post"> <อินพุต type = "hidden" name = "โทเค็น" value = "<%= โทเค็น%>"/> จำนวนการถ่ายโอน: <อินพุตประเภท = "text" name = "money" min = "1"รหัสใน transferservlet
@webservlet ("/trans") การถ่ายโอนระดับสาธารณะ Public Extion Httpservlet {ส่วนตัวคงที่สุดท้าย Long SerialVersionUID = 1L; บริการโมฆะที่ได้รับการป้องกัน (httpservletrequest REQ, httpservletResponse resp) พ่น servletexception, ioexception {req.setcharacterencoding ("UTF-8"); resp.setContentType ("ข้อความ/html; charset = utf-8"); PrintWriter out = resp.getWriter (); // รับค่าโทเค็นในฟอร์มสตริงโทเค็น = req.getParameter ("โทเค็น"); // รับค่าโทเค็นในสตริงเซสชัน sessionToken = (สตริง) req.getSession (). getAttribute ("TOKEN_IN_SESSION"); // โทเค็นในเซสชั่นนั้นว่างเปล่าเพราะโทเค็นในเซสชั่นนั้นสามารถทำลายได้ถ้า (โทเค็น. เท่า (เซสชัน)) {// ระบุว่าโทเค็นเป็น req.getSession () การลบ ("token_in_session"); สตริงเงิน = req.getParameter ("เงิน"); System.out.println ("การโอนจำนวน:"+เงิน); out.print ("โอนจำนวน:"+เงิน); // ในที่สุดก็ทำลายโทเค็นในเซสชัน} // ถ้าโทเค็นแตกต่างกันหมายความว่ามันเป็นการส่งซ้ำและไม่สามารถส่งได้}}}จากนั้นเพื่อไม่ให้ปรากฏในรหัส Java ในไฟล์ JSP ให้สร้างและข้ามโทเค็นในเซิร์ฟเล็ตอื่น
@webservlet ("/transfer") คลาสสาธารณะ copyoftransferservlet ขยาย httpservlet {ส่วนตัวคงที่สุดท้าย long serialversionuid = 1l; บริการโมฆะที่ได้รับการป้องกัน (httpservletrequest req, httpservletresponse resp) พ่น servletexception, ioexception {// สร้างโทเค็นและข้ามไปที่ subment.jsp สตริงโทเค็น = uuid.randomuuid () toString (); System.out.println (โทเค็น); req.getSession (). setAttribute ("TOKEN_IN_SESSION", โทเค็น); req.setAttribute ("โทเค็น" โทเค็น); req.getRequestDispatcher ("/views/repeatsubmit/subment.jsp"). forward (req, resp); -นี่คือสิ่งที่ไฟล์ JSP ดูเหมือนตอนนี้
<h3> การถ่ายโอนอินเตอร์เฟส </h3> <form action = "/trans" method = "post"> <อินพุต type = "hidden" name = "โทเค็น" value = "$ {โทเค็น}"/> จำนวนการถ่ายโอน: <อินพุต type = "text" name = "money" min = "1"มันสะอาดกว่าด้านบนและเรียบร้อยมากขึ้น แต่ก็ยังไม่รู้สึกดีเพราะถ้าคุณต้องการใช้ในที่อื่นคุณต้องสร้างโทเค็นตรวจสอบโทเค็นและลบโทเค็น
tokenutil.java
// Token Tool Class // สร้างโทเค็น // ตรวจสอบโทเค็น // ทำลายโทเค็นคลาสสาธารณะโทเค็นทิล {สตริงคงสุดท้ายส่วนตัว TOKEN_IN_SESSION = "TOKEN_IN_SESSION"; โมฆะคงที่สาธารณะ savatoken (httpservletrequest req) {สตริงโทเค็น = uuid.randomuuid (). toString (); System.out.println (โทเค็น); req.getSession (). setAttribute (TOKEN_IN_SESSION, โทเค็น); req.setAttribute ("โทเค็น" โทเค็น); } public boolean validateToken (httpservletrequest req, string tokeninrequest) {// รับค่าโทเค็นใน SessionString SessionToken = (String) req.getSession () GetAttribute (TOKEN_IN_SESSION); if (tokeninRequest.equals (sessionToken)) {req.getSession (). RemoveAttribute (TOKEN_IN_SESSION); กลับมาจริง; } return false; -นี่เป็นเรื่องปกติ ผู้ใช้ต้องการเรียกคลาสเครื่องมือนี้เท่านั้นและไม่จำเป็นต้องเขียนชุดการดำเนินงานเช่นการสร้างโทเค็น
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น