Câu trả lời:
requestDispatcher - phương thức Forward ()
Khi chúng tôi sử dụng
forward
phương thức, yêu cầu được chuyển đến một tài nguyên khác trong cùng một máy chủ để xử lý thêm.Trong trường hợp
forward
, bộ chứa web xử lý tất cả xử lý nội bộ và máy khách hoặc trình duyệt không liên quan.Khi
forward
được gọi trênrequestDispatcher
đối tượng, chúng ta chuyển các đối tượng yêu cầu và phản hồi, vì vậy đối tượng yêu cầu cũ của chúng ta có mặt trên tài nguyên mới sẽ xử lý yêu cầu của chúng ta.Trực quan, chúng tôi không thể nhìn thấy địa chỉ được chuyển tiếp, nó là minh bạch.
Sử dụng
forward()
phương pháp nhanh hơnsendRedirect
.Khi chúng tôi chuyển hướng sử dụng chuyển tiếp và chúng tôi muốn sử dụng cùng một dữ liệu trong một tài nguyên mới, chúng tôi có thể sử dụng
request.setAttribute()
khi chúng tôi có sẵn một đối tượng yêu cầu.SendRedirect
Trong trường hợp
sendRedirect
, yêu cầu được chuyển đến một tài nguyên khác, đến một tên miền khác hoặc đến một máy chủ khác để xử lý thêm.Khi bạn sử dụng
sendRedirect
, vùng chứa chuyển yêu cầu đến máy khách hoặc trình duyệt, do đó URL được cung cấp bên trongsendRedirect
phương thức được hiển thị dưới dạng yêu cầu mới cho máy khách.Trong trường hợp
sendRedirect
cuộc gọi, các đối tượng yêu cầu và phản hồi cũ sẽ bị mất vì trình duyệt được coi là yêu cầu mới của trình duyệt.Trong thanh địa chỉ, chúng tôi có thể thấy địa chỉ được chuyển hướng mới. Nó không minh bạch.
sendRedirect
chậm hơn vì cần thêm một chuyến đi khứ hồi, bởi vì một yêu cầu hoàn toàn mới được tạo ra và đối tượng yêu cầu cũ bị mất. Yêu cầu hai trình duyệt.Nhưng trong
sendRedirect
, nếu chúng ta muốn sử dụng cùng một dữ liệu cho một tài nguyên mới, chúng ta phải lưu trữ dữ liệu trong phiên hoặc chuyển cùng với URL.Cái nào tốt?
Nó phụ thuộc vào kịch bản cho phương pháp nào hữu ích hơn.
Nếu bạn muốn điều khiển được chuyển đến máy chủ hoặc ngữ cảnh mới và nó được coi là nhiệm vụ hoàn toàn mới, thì chúng tôi sẽ thực hiện
sendRedirect
. Nói chung, nên sử dụng chuyển tiếp nếu thao tác có thể được lặp lại một cách an toàn khi tải lại trình duyệt của trang web và sẽ không ảnh hưởng đến kết quả.
Trong thế giới phát triển web, thuật ngữ "chuyển hướng" là hành động gửi cho khách hàng một phản hồi HTTP trống chỉ với một Location
tiêu đề chứa URL mới mà khách hàng phải gửi yêu cầu GET hoàn toàn mới. Nên về cơ bản:
some.jsp
.Location: other.jsp
tiêu đềother.jsp
(điều này được phản ánh trên thanh địa chỉ trình duyệt!)other.jsp
.Bạn có thể theo dõi nó với bộ công cụ dành cho nhà phát triển dựng sẵn / addon của trình duyệt web. Nhấn F12 trong Chrome / IE9 / Fireorms và kiểm tra phần "Mạng" để xem.
Chính xác những điều trên là đạt được sendRedirect("other.jsp")
. Các RequestDispatcher#forward()
không gửi một chuyển hướng. Thay vào đó, nó sử dụng nội dung của trang đích làm phản hồi HTTP.
some.jsp
.other.jsp
.Tuy nhiên, như yêu cầu HTTP ban đầu là some.jsp
, URL trong thanh địa chỉ trình duyệt vẫn không thay đổi. Ngoài ra, bất kỳ thuộc tính yêu cầu nào được đặt trong bộ điều khiển phía sau some.jsp
sẽ có sẵn other.jsp
. Điều này không xảy ra trong quá trình chuyển hướng bởi vì về cơ bản, bạn buộc khách hàng phải tạo một yêu cầu HTTP mớiother.jsp
, từ đó loại bỏ yêu cầu ban đầu some.jsp
bao gồm tất cả các thông báo của nó.
Điều RequestDispatcher
này cực kỳ hữu ích trong mô hình MVC và / hoặc khi bạn muốn ẩn JSP khỏi truy cập trực tiếp. Bạn có thể đặt JSP trong /WEB-INF
thư mục và sử dụng một Servlet
điều khiển, tiền xử lý và hậu xử lý các yêu cầu. Các tệp tin trong /WEB-INF
thư mục không thể truy cập trực tiếp bằng URL, nhưng Servlet
có thể truy cập chúng bằng cách sử dụng RequestDispatcher#forward()
.
Bạn có thể ví dụ có một tập tin JSP trong /WEB-INF/login.jsp
và LoginServlet
được ánh xạ vào một url-pattern
số /login
. Khi bạn gọi http://example.com/context/login
, thì servlet doGet()
sẽ được gọi. Bạn có thể thực hiện bất kỳ công cụ xử lý trước nào trong đó và cuối cùng chuyển tiếp yêu cầu như:
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
Khi bạn gửi biểu mẫu, thông thường bạn muốn sử dụng POST
:
<form action="login" method="post">
Bằng cách này, các servlet doPost()
sẽ được gọi và bạn có thể thực hiện bất kỳ công cụ xử lý bài đăng nào trong đó (ví dụ: xác thực, logic nghiệp vụ, đăng nhập người dùng, v.v.).
Nếu có bất kỳ lỗi nào, thì thông thường bạn muốn chuyển tiếp yêu cầu trở lại cùng một trang và hiển thị các lỗi ở đó bên cạnh các trường nhập liệu, v.v. Bạn có thể sử dụng RequestDispatcher
cho việc này.
Nếu a POST
thành công, thông thường bạn muốn chuyển hướng yêu cầu, để yêu cầu sẽ không được gửi lại khi người dùng làm mới yêu cầu (ví dụ: nhấn F5 hoặc điều hướng lại trong lịch sử).
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.
}
Do đó, một chuyển hướng hướng dẫn khách hàng thực hiện một GET
yêu cầu mới trên URL đã cho. Làm mới yêu cầu sau đó sẽ chỉ làm mới yêu cầu được chuyển hướng chứ không phải yêu cầu ban đầu. Điều này sẽ tránh "đệ trình kép" và nhầm lẫn và trải nghiệm người dùng xấu. Đây cũng được gọi là POST-Redirect-GET
mô hình .
Các RequestDispatcher
giao diện cho phép bạn để làm một phía máy chủ chuyển tiếp / bao gồm trong khi sendRedirect()
thực hiện một chuyển hướng phía khách hàng. Trong chuyển hướng phía máy khách, máy chủ sẽ gửi lại mã trạng thái HTTP 302
(chuyển hướng tạm thời) khiến trình duyệt web đưa ra GET
yêu cầu HTTP hoàn toàn mới cho nội dung tại vị trí được chuyển hướng. Ngược lại, khi sử dụng RequestDispatcher
giao diện, bao gồm / chuyển tiếp đến tài nguyên mới được xử lý hoàn toàn ở phía máy chủ.
forward
, không chuyển hướng.
Sự khác biệt quan trọng chính giữa phương thức Forward () và sendRedirect () là trong trường hợp Forward (), chuyển hướng xảy ra ở cuối máy chủ và không hiển thị cho máy khách, nhưng trong trường hợp sendRedirect (), chuyển hướng xảy ra ở cuối máy khách và nó hiển thị cho khách hàng
Một trong hai phương pháp này có thể là "tốt hơn", nghĩa là phù hợp hơn, tùy thuộc vào những gì bạn muốn làm.
Chuyển hướng phía máy chủ sẽ nhanh hơn khi bạn lấy dữ liệu từ một trang khác mà không thực hiện một chuyến đi khứ hồi tới trình duyệt. Nhưng URL được thấy trong trình duyệt vẫn là địa chỉ ban đầu, vì vậy bạn đang tạo ra một chút không nhất quán ở đó.
Chuyển hướng phía máy khách linh hoạt hơn khi nó có thể đưa bạn đến một máy chủ hoàn toàn khác hoặc thay đổi giao thức (ví dụ: từ HTTP sang HTTPS) hoặc cả hai. Và trình duyệt nhận biết URL mới. Nhưng phải mất thêm một lần nữa qua lại giữa máy chủ và máy khách.
SendRedirect()
sẽ tìm kiếm nội dung giữa các máy chủ. nó chậm vì phải thân mật với trình duyệt bằng cách gửi URL của nội dung. sau đó trình duyệt sẽ tạo một yêu cầu mới cho nội dung trong cùng một máy chủ hoặc trong một máy chủ khác.
RquestDispatcher
Tôi nghĩ là để tìm kiếm nội dung trong máy chủ. Đó là quá trình phía máy chủ và nó nhanh hơn so với SendRedirect()
phương thức. nhưng điều đáng nói là nó sẽ không thân mật với trình duyệt mà máy chủ đang tìm kiếm ngày hoặc nội dung được yêu cầu, nó sẽ không yêu cầu trình duyệt thay đổi URL trong tab URL. do đó nó gây ra sự bất tiện nhỏ cho người dùng.
Về mặt kỹ thuật nên sử dụng chuyển hướng nếu chúng ta cần chuyển điều khiển sang các miền khác nhau hoặc để đạt được sự phân tách nhiệm vụ.
Ví dụ: trong ứng dụng thanh toán, trước tiên chúng tôi thực hiện PaymentProcess và sau đó chuyển hướng đến displayPaymentInfo. Nếu ứng dụng khách làm mới trình duyệt thì chỉ displayPaymentInfo sẽ được thực hiện lại và PaymentProcess sẽ không được lặp lại. Nhưng nếu chúng ta sử dụng chuyển tiếp trong kịch bản này, cả PaymentProcess và displayPaymentInfo sẽ được thực hiện lại một cách tuần tự, điều này có thể dẫn đến dữ liệu không nhất quán.
Đối với các kịch bản khác, chuyển tiếp là hiệu quả để sử dụng vì nó nhanh hơn sendRedirect
Request Dispatcher là một Giao diện được sử dụng để gửi yêu cầu hoặc phản hồi từ tài nguyên web đến tài nguyên web khác. Nó chứa chủ yếu hai phương pháp.
request.forward(req,res)
: Phương pháp này được sử dụng chuyển tiếp yêu cầu từ tài nguyên web này sang tài nguyên khác. tức là từ một servlet này sang một servlet khác hoặc từ một ứng dụng web này đến một ứng dụng web khác.
response.include(req,res)
: Phương thức này được sử dụng bao gồm phản hồi của một servlet với một servlet khác
LƯU Ý: Bằng cách sử dụng Bộ điều phối yêu cầu, chúng tôi có thể chuyển tiếp hoặc bao gồm yêu cầu hoặc phản hồi trong cùng một máy chủ.
request.sendRedirect()
: Bằng cách sử dụng điều này, chúng tôi có thể chuyển tiếp hoặc bao gồm yêu cầu hoặc phản hồi trên các máy chủ khác nhau. Trong trường hợp này, khách hàng có được sự thân mật trong khi chuyển hướng trang nhưng trong quá trình trên, khách hàng sẽ không nhận được sự thân mật
Đơn giản chỉ cần chênh lệch giữa Forward(ServletRequest request, ServletResponse response)
và sendRedirect(String url)
là
ở đằng trước():
forward()
phương pháp được thực hiện ở phía máy chủ.forward ()
phương thức được cung cấp bởi thùng chứa servlet.forward()
phương pháp là nhanh hơn so với sendRedirect()
phương pháp.RequestDispatcher
giao diện.sendRedirect ():
response.sendRedirect("..")
trang index.jsp của trang web. Nhưng điều đó bỏ lỡ các tệp css và một số văn bản từ trang jsp, dẫn đến tải một phần của trang. Nhưng khi tôi đặt trang chào mừng của trang web thành index.jsp, mọi thứ sẽ hoạt động tốt và tải trang hoàn tất. Điều gì là sai với chuyển hướng?