RequestDispatcher.forward () so với HttpServletResponse.sendRedirect ()


Câu trả lời:


106

requestDispatcher - phương thức Forward ()

  1. Khi chúng tôi sử dụng forwardphươ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.

  2. 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.

  3. Khi forwardđược gọi trên requestDispatcherđố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.

  4. 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.

  5. Sử dụng forward()phương pháp nhanh hơn sendRedirect.

  6. 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

  1. 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.

  2. 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 trong sendRedirectphương thức được hiển thị dưới dạng yêu cầu mới cho máy khách.

  3. Trong trường hợp sendRedirectcuộ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.

  4. 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.

  5. sendRedirectchậ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.

  6. 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ả.

Nguồn


161

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 Locationtiê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:

  • Khách hàng gửi yêu cầu HTTP đến some.jsp.
  • Máy chủ gửi phản hồi HTTP trở lại với Location: other.jsptiêu đề
  • Khách hàng gửi yêu cầu HTTP đến other.jsp(điều này được phản ánh trên thanh địa chỉ trình duyệt!)
  • Máy chủ gửi phản hồi HTTP trở lại với nội dung của 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.

  • Khách hàng gửi yêu cầu HTTP đến some.jsp.
  • Máy chủ gửi phản hồi HTTP trở lại với nội dung của 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.jspsẽ 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.jspbao gồm tất cả các thông báo của nó.


Điều RequestDispatchernà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-INFthư 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-INFthư mục không thể truy cập trực tiếp bằng URL, nhưng Servletcó 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.jspLoginServletđược ánh xạ vào một url-patternsố /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 RequestDispatchercho việc này.

Nếu a POSTthà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 GETyê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-GETmô hình .

Xem thêm:


Khi tôi chuyển hướng từ một servlet đến một trang jsp, trang jsp được tải một phần, như trong stackoverflow.com/questions/12337624/ . Tôi muốn thứ đầu tiên chạy khi bất kỳ ai nhấn foo.com là servlet. Từ servlet tôi làm một 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?
saplingPro

20

Các RequestDispatchergiao 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 GETyê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 RequestDispatchergiao 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ủ.


Và sau này là thực sự forward, không chuyển hướng.
Adeel Ansari

5

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

nhập mô tả hình ảnh ở đây


2
Một bức tranh đáng giá ngàn lời nói :)
Eugen Labun

4

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.


2
Phân đoạn này ngay tại đây không được đề cập đủ trên web: "hoặc thay đổi giao thức (ví dụ: từ HTTP sang HTTPS) hoặc cả hai"
Perdomoff

3

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.

RquestDispatcherTô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.


1

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


0

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.

  1. 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.

  2. 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


-1

Đơn giản chỉ cần chênh lệch giữa Forward(ServletRequest request, ServletResponse response)sendRedirect(String url)

ở đằng trước():

  1. Các forward()phương pháp được thực hiện ở phía máy chủ.
  2. Yêu cầu được chuyển đến tài nguyên khác trong cùng một máy chủ.
  3. Nó không phụ thuộc vào giao thức yêu cầu của máy khách vì forward ()phương thức được cung cấp bởi thùng chứa servlet.
  4. Yêu cầu được chia sẻ bởi tài nguyên đích.
  5. Chỉ có một cuộc gọi được sử dụng trong phương pháp này.
  6. Nó có thể được sử dụng trong máy chủ.
  7. Chúng tôi không thể thấy tin nhắn chuyển tiếp, nó là minh bạch.
  8. Các forward()phương pháp là nhanh hơn so với sendRedirect()phương pháp.
  9. Nó được khai báo trong RequestDispatchergiao diện.

sendRedirect ():

  1. Phương thức sendRedirect () được thực thi ở phía máy khách.
  2. Yêu cầu được chuyển đến tài nguyên khác đến máy chủ khác.
  3. Phương thức sendRedirect () được cung cấp theo HTTP để nó chỉ có thể được sử dụng với các máy khách HTTP.
  4. Yêu cầu mới được tạo cho tài nguyên đích.
  5. Hai cuộc gọi yêu cầu và phản hồi được tiêu thụ.
  6. Nó có thể được sử dụng trong và ngoài máy chủ.
  7. Chúng ta có thể thấy địa chỉ chuyển hướng, nó không minh bạch.
  8. Phương thức sendRedirect () chậm hơn vì khi yêu cầu mới được tạo, đối tượng yêu cầu cũ bị mất.
  9. Nó được khai báo trong HttpServletResponse.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.