อะไรคือความแตกต่างของแนวคิดระหว่างforward()และsendRedirect()?
อะไรคือความแตกต่างของแนวคิดระหว่างforward()และsendRedirect()?
คำตอบ:
requestDispatcher - ไปข้างหน้า () วิธีการ
เมื่อเราใช้
forwardวิธีนี้คำขอจะถูกโอนไปยังทรัพยากรอื่นภายในเซิร์ฟเวอร์เดียวกันเพื่อดำเนินการต่อไปในกรณีของ
forwardเว็บคอนเทนเนอร์จะจัดการการประมวลผลทั้งหมดภายในและไคลเอนต์หรือเบราว์เซอร์จะไม่เกี่ยวข้องเมื่อ
forwardถูกเรียกบนrequestDispatcherอ็อบเจ็กต์เราจะส่งผ่านคำร้องขอและอ็อบเจ็กต์การตอบสนองดังนั้นอ็อบเจ็กต์คำขอเก่าของเราจึงอยู่ในทรัพยากรใหม่ซึ่งจะดำเนินการตามคำขอของเราด้วยสายตาเราไม่สามารถเห็นที่อยู่ที่ส่งต่อได้ แต่เป็นแบบโปร่งใส
โดยใช้วิธีการที่เร็วกว่า
forward()sendRedirectเมื่อเราเปลี่ยนเส้นทางโดยใช้ไปข้างหน้าและเราต้องการใช้ข้อมูลเดียวกันในทรัพยากรใหม่เราสามารถใช้
request.setAttribute()เมื่อเรามีวัตถุขอsendRedirect
ในกรณีนี้
sendRedirectคำขอจะถูกโอนไปยังทรัพยากรอื่นไปยังโดเมนอื่นหรือไปยังเซิร์ฟเวอร์อื่นเพื่อดำเนินการต่อไปเมื่อคุณใช้
sendRedirectคอนเทนเนอร์จะโอนคำขอไปยังไคลเอนต์หรือเบราว์เซอร์ดังนั้น URL ที่ระบุในsendRedirectเมธอดจะมองเห็นได้ว่าเป็นคำขอใหม่สำหรับไคลเอ็นต์ในกรณีของการ
sendRedirectโทรคำขอเก่าและอ็อบเจ็กต์การตอบกลับจะหายไปเนื่องจากเบราว์เซอร์ถือว่าเป็นคำขอใหม่ในแถบที่อยู่เราจะเห็นที่อยู่ที่เปลี่ยนเส้นทางใหม่ มันไม่โปร่งใส
sendRedirectช้ากว่าเนื่องจากต้องใช้การเดินทางรอบพิเศษหนึ่งครั้งเนื่องจากมีการสร้างคำขอใหม่ทั้งหมดและวัตถุคำขอเก่าจะสูญหายไป จำเป็นต้องมีคำขอเบราว์เซอร์สองรายการแต่ใน
sendRedirectกรณีที่เราต้องการใช้ข้อมูลเดียวกันกับทรัพยากรใหม่เราต้องจัดเก็บข้อมูลในเซสชันหรือส่งต่อไปพร้อมกับ URLตัวไหนดีครับ?
ขึ้นอยู่กับสถานการณ์ว่าวิธีใดมีประโยชน์มากกว่า
sendRedirectถ้าคุณต้องการควบคุมการโอนไปยังเซิร์ฟเวอร์ใหม่หรือบริบทและมันจะถือว่าเป็นงานใหม่ที่สมบูรณ์แล้วเราไป โดยทั่วไปควรใช้การส่งต่อหากการดำเนินการสามารถทำซ้ำได้อย่างปลอดภัยเมื่อเบราว์เซอร์โหลดหน้าเว็บซ้ำและจะไม่ส่งผลต่อผลลัพธ์
ในโลกของการพัฒนาเว็บคำว่า "เปลี่ยนเส้นทาง" คือการส่งการตอบสนอง HTTP ที่ว่างเปล่าให้กับลูกค้าโดยมีเพียงLocationส่วนหัวที่มี URL ใหม่ซึ่งไคลเอ็นต์ต้องส่งคำขอ GET ใหม่ล่าสุด โดยพื้นฐานแล้ว:
some.jspไปLocation: other.jspส่วนหัวother.jsp(สิ่งนี้จะแสดงในแถบที่อยู่ของเบราว์เซอร์!)other.jsp.คุณสามารถติดตามได้ด้วยชุดเครื่องมือสำหรับนักพัฒนา builtin / addon ของเว็บเบราว์เซอร์ กด F12 ใน Chrome / IE9 / Firebug และตรวจสอบส่วน "เครือข่าย" เพื่อดู
sendRedirect("other.jsp")ตรงข้างต้นจะทำได้โดย RequestDispatcher#forward()ไม่ส่งการเปลี่ยนเส้นทาง แต่จะใช้เนื้อหาของเพจเป้าหมายเป็นการตอบสนอง HTTP
some.jspไปother.jsp.อย่างไรก็ตามตามคำขอ HTTP เดิมsome.jspURL ในแถบที่อยู่ของเบราว์เซอร์จะไม่เปลี่ยนแปลง นอกจากนี้แอตทริบิวต์คำขอใด ๆ ที่ตั้งค่าไว้ในคอนโทรลเลอร์ที่อยู่เบื้องหลังsome.jspother.jspจะสามารถใช้ได้ใน สิ่งนี้จะไม่เกิดขึ้นระหว่างการเปลี่ยนเส้นทางเนื่องจากโดยพื้นฐานแล้วคุณบังคับให้ไคลเอนต์สร้างคำขอ HTTP ใหม่ในที่other.jspนี้โดยจะทิ้งคำขอเดิมโดยsome.jspรวมแอตทริบิวต์ทั้งหมดไว้ด้วย
RequestDispatcherเป็นประโยชน์อย่างมากในกระบวนทัศน์ MVC และ / หรือเมื่อคุณต้องการที่จะซ่อนตัวจากการเข้าถึงโดยตรงของ JSP คุณสามารถใส่ JSP ใน/WEB-INFโฟลเดอร์และใช้Servletตัวควบคุมประมวลผลล่วงหน้าและประมวลผลคำขอภายหลัง JSPs ใน/WEB-INFโฟลเดอร์ที่ไม่สามารถเข้าถึงได้โดยตรงจาก URL แต่สามารถเข้าถึงได้โดยใช้ServletRequestDispatcher#forward()
เช่นคุณสามารถมีไฟล์ JSP ใน/WEB-INF/login.jspและLoginServletซึ่งเป็นแมปบนของurl-pattern /loginเมื่อคุณเรียกใช้http://example.com/context/loginservlet doGet()จะถูกเรียกใช้ คุณสามารถทำอะไรก็ได้ก่อนการประมวลผลที่นั่นและส่งต่อคำขอในที่สุดเช่น:
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
เมื่อคุณส่งแบบฟอร์มโดยปกติคุณต้องการใช้POST:
<form action="login" method="post">
วิธีนี้คือ servlet doPost()จะเรียกใช้และคุณสามารถทำการประมวลผลโพสต์ใด ๆในที่นั่น (เช่นการตรวจสอบความถูกต้องตรรกะทางธุรกิจล็อกอินผู้ใช้ ฯลฯ )
หากมีข้อผิดพลาดใด ๆ ตามปกติคุณต้องการ ส่งต่อคำขอกลับไปที่หน้าเดิมและแสดงข้อผิดพลาดที่นั่นถัดจากช่องป้อนข้อมูลเป็นต้น คุณสามารถใช้RequestDispatcherสำหรับสิ่งนี้
หากPOSTประสบความสำเร็จคุณมักจะต้องการเปลี่ยนเส้นทางเพื่อที่จะไม่ส่งคำขออีกครั้งเมื่อผู้ใช้รีเฟรชคำขอ (เช่นกด F5 หรือย้อนกลับไปในประวัติ)
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user); // Login user.
response.sendRedirect("home"); // Redirects to http://example.com/context/home after succesful login.
} else {
request.setAttribute("error", "Unknown login, please try again."); // Set error.
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to same page so that you can display error.
}
เปลี่ยนเส้นทางจึงแนะนำให้ลูกค้าที่จะยิงใหม่GETคำขอใน URL ที่กำหนด การรีเฟรชคำขอจะรีเฟรชเฉพาะคำขอที่เปลี่ยนเส้นทางไม่ใช่คำขอเริ่มต้น วิธีนี้จะหลีกเลี่ยง "การส่งซ้ำ" และความสับสนและประสบการณ์ของผู้ใช้ที่ไม่ดี นี้เรียกว่ายังเป็นรูปแบบPOST-Redirect-GET
RequestDispatcherอินเตอร์เฟซที่ช่วยให้คุณทำฝั่งเซิร์ฟเวอร์ไปข้างหน้า / รวมในขณะที่sendRedirect()ไม่ได้เปลี่ยนเส้นทางฝั่งไคลเอ็นต์ ในการเปลี่ยนเส้นทางฝั่งไคลเอ็นต์เซิร์ฟเวอร์จะส่งรหัสสถานะ HTTP ของ302(การเปลี่ยนเส้นทางชั่วคราว) กลับซึ่งทำให้เว็บเบราว์เซอร์GETส่งคำขอHTTP ใหม่ล่าสุดสำหรับเนื้อหาที่ตำแหน่งที่เปลี่ยนเส้นทาง ในทางตรงกันข้ามเมื่อใช้RequestDispatcherอินเทอร์เฟซการรวม / ส่งต่อไปยังทรัพยากรใหม่จะได้รับการจัดการทั้งหมดที่ฝั่งเซิร์ฟเวอร์
forwardไม่ใช่เปลี่ยนเส้นทาง
ความแตกต่างที่สำคัญหลักระหว่างเมธอด forward () และ sendRedirect () คือในกรณีของ forward () การเปลี่ยนเส้นทางจะเกิดขึ้นที่ส่วนท้ายของเซิร์ฟเวอร์และไคลเอนต์ไม่สามารถมองเห็นได้ แต่ในกรณีของ sendRedirect () การเปลี่ยนเส้นทางจะเกิดขึ้นที่ส่วนไคลเอนต์และมองเห็นได้ ให้กับลูกค้า
วิธีใดวิธีหนึ่งเหล่านี้อาจ "ดีกว่า" เช่นเหมาะสมกว่าขึ้นอยู่กับสิ่งที่คุณต้องการทำ
การเปลี่ยนเส้นทางฝั่งเซิร์ฟเวอร์จะเร็วกว่าเมื่อคุณได้รับข้อมูลจากเพจอื่นโดยไม่ต้องเดินทางไปที่เบราว์เซอร์ แต่ URL ที่เห็นในเบราว์เซอร์ยังคงเป็นที่อยู่เดิมดังนั้นคุณจึงสร้างความไม่สอดคล้องกันเล็กน้อยที่นั่น
การเปลี่ยนเส้นทางฝั่งไคลเอ็นต์มีความหลากหลายมากกว่าเนื่องจากสามารถส่งคุณไปยังเซิร์ฟเวอร์ที่แตกต่างกันโดยสิ้นเชิงหรือเปลี่ยนโปรโตคอล (เช่นจาก HTTP เป็น HTTPS) หรือทั้งสองอย่าง และเบราว์เซอร์ทราบถึง URL ใหม่ แต่ต้องใช้เวลากลับไปกลับมาระหว่างเซิร์ฟเวอร์และไคลเอนต์
SendRedirect()จะค้นหาเนื้อหาระหว่างเซิร์ฟเวอร์ ช้าเนื่องจากต้องทำให้เบราว์เซอร์ใกล้ชิดโดยการส่ง URL ของเนื้อหา จากนั้นเบราว์เซอร์จะสร้างคำขอใหม่สำหรับเนื้อหาภายในเซิร์ฟเวอร์เดียวกันหรือในเซิร์ฟเวอร์อื่น
RquestDispatcherมีไว้สำหรับค้นหาเนื้อหาภายในเซิร์ฟเวอร์ที่ฉันคิด เป็นกระบวนการฝั่งเซิร์ฟเวอร์และเร็วกว่าเมื่อเทียบกับSendRedirect()วิธีการ แต่สิ่งที่สำคัญก็คือมันจะไม่สนิทสนมกับเบราว์เซอร์ที่เซิร์ฟเวอร์กำลังค้นหาวันที่หรือเนื้อหาที่ต้องการและจะไม่ขอให้เบราว์เซอร์เปลี่ยน URL ในแท็บ URL ดังนั้นจึงทำให้ผู้ใช้ไม่สะดวกเล็กน้อย
ควรใช้การเปลี่ยนเส้นทางทางเทคนิคในกรณีที่เราต้องการโอนการควบคุมไปยังโดเมนอื่นหรือเพื่อแยกงานออกจากกัน
ตัวอย่างเช่นในแอปพลิเคชันการชำระเงินเราจะดำเนินการ PaymentProcess ก่อนแล้วจึงเปลี่ยนเส้นทางไปที่ displayPaymentInfo หากไคลเอนต์รีเฟรชเบราว์เซอร์เฉพาะ displayPaymentInfo จะทำอีกครั้งและ PaymentProcess จะไม่ทำซ้ำ แต่ถ้าเราใช้ไปข้างหน้าในสถานการณ์นี้ทั้ง PaymentProcess และ displayPaymentInfo จะถูกดำเนินการใหม่ตามลำดับซึ่งอาจส่งผลให้ข้อมูลไม่สอดคล้องกัน
สำหรับสถานการณ์อื่น ๆ การส่งต่อมีประสิทธิภาพในการใช้เนื่องจากเร็วกว่า sendRedirect
Request Dispatcher คืออินเทอร์เฟซที่ใช้เพื่อส่งคำขอหรือการตอบกลับจากทรัพยากรบนเว็บไปยังทรัพยากรบนเว็บอื่น ประกอบด้วยสองวิธีเป็นหลัก
request.forward(req,res): วิธีนี้ใช้ส่งต่อคำขอจากทรัพยากรบนเว็บหนึ่งไปยังทรัพยากรอื่น เช่นจาก servlet หนึ่งไปยัง servlet อื่นหรือจากเว็บแอปพลิเคชันหนึ่งไปยัง web appliacation อื่น
response.include(req,res): วิธีนี้ใช้รวมการตอบสนองของ servlet หนึ่งไปยัง servlet อื่น
หมายเหตุ: โดยใช้ Request Dispatcher เราสามารถส่งต่อหรือรวมคำขอหรือการตอบกลับไว้ในเซิร์ฟเวอร์เดียวกันได้
request.sendRedirect(): ด้วยการใช้สิ่งนี้เราสามารถส่งต่อหรือรวมคำขอหรือการตอบสนองข้ามเซิร์ฟเวอร์ต่างๆ ในกรณีนี้ลูกค้าจะได้รับการข่มขู่ในขณะที่เปลี่ยนเส้นทางเพจ แต่ในขั้นตอนข้างต้นลูกค้าจะไม่ได้รับการข่มขู่
ความแตกต่างระหว่างForward(ServletRequest request, ServletResponse response)และsendRedirect(String url)คือ
ส่งต่อ ():
forward()วิธีการที่จะดำเนินการในฝั่งเซิร์ฟเวอร์forward ()เมธอดถูกจัดเตรียมโดย servlet containerforward()เป็นวิธีการที่เร็วกว่าsendRedirect()วิธีการRequestDispatcherอินเทอร์เฟซsendRedirect ():
response.sendRedirect("..")ไปที่หน้า index.jsp ของเว็บไซต์ แต่นั่นทำให้พลาดไฟล์ css และข้อความบางส่วนจากหน้า jsp ซึ่งนำไปสู่การโหลดหน้าบางส่วน แต่เมื่อฉันทำให้หน้ายินดีต้อนรับของเว็บไซต์เป็น index.jsp ทุกอย่างทำงานได้ดีและโหลดหน้าเว็บเสร็จสมบูรณ์ เกิดอะไรขึ้นกับการเปลี่ยนเส้นทาง?