อะไรคือความแตกต่างของแนวคิดระหว่าง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.jsp
URL ในแถบที่อยู่ของเบราว์เซอร์จะไม่เปลี่ยนแปลง นอกจากนี้แอตทริบิวต์คำขอใด ๆ ที่ตั้งค่าไว้ในคอนโทรลเลอร์ที่อยู่เบื้องหลังsome.jsp
other.jsp
จะสามารถใช้ได้ใน สิ่งนี้จะไม่เกิดขึ้นระหว่างการเปลี่ยนเส้นทางเนื่องจากโดยพื้นฐานแล้วคุณบังคับให้ไคลเอนต์สร้างคำขอ HTTP ใหม่ในที่other.jsp
นี้โดยจะทิ้งคำขอเดิมโดยsome.jsp
รวมแอตทริบิวต์ทั้งหมดไว้ด้วย
RequestDispatcher
เป็นประโยชน์อย่างมากในกระบวนทัศน์ MVC และ / หรือเมื่อคุณต้องการที่จะซ่อนตัวจากการเข้าถึงโดยตรงของ JSP คุณสามารถใส่ JSP ใน/WEB-INF
โฟลเดอร์และใช้Servlet
ตัวควบคุมประมวลผลล่วงหน้าและประมวลผลคำขอภายหลัง JSPs ใน/WEB-INF
โฟลเดอร์ที่ไม่สามารถเข้าถึงได้โดยตรงจาก URL แต่สามารถเข้าถึงได้โดยใช้Servlet
RequestDispatcher#forward()
เช่นคุณสามารถมีไฟล์ JSP ใน/WEB-INF/login.jsp
และLoginServlet
ซึ่งเป็นแมปบนของurl-pattern
/login
เมื่อคุณเรียกใช้http://example.com/context/login
servlet 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 ทุกอย่างทำงานได้ดีและโหลดหน้าเว็บเสร็จสมบูรณ์ เกิดอะไรขึ้นกับการเปลี่ยนเส้นทาง?