1. 程式人生 > >同時呼叫getOutputStream()和getWriter()出現的問題以及請求轉發和請求重定向的區別

同時呼叫getOutputStream()和getWriter()出現的問題以及請求轉發和請求重定向的區別

package response;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//同時呼叫getOutputStream()和getWriter()會拋java.lang.IllegalStateException異常
public class
ResponseDemo8 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //呼叫了getOutputStream()和getWriter()不能同時呼叫 response.getOutputStream(); response.getWriter(); //用轉發也不能同時呼叫getOutputStream()和getWriter(),因為始終是同一個request和response
//重定向可以同時呼叫getOutputStream()和getWriter(),因為會產生兩個request和response } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

請求轉發(Forward)和請求重定向(Redirect):
一個比喻:
小張向小李傳送一次請求,想讓他完成某項工作,當小李接受到請求時,發現自己完成不了,又請求小王幫忙,小王接收到小李請求之後最終完成了該項工作,並把最後的結果交給了小張。這個過程就是請求轉發,在此期間,小張只發送了一次請求,他只知道把任務交給了小李,至於小李是如何完成的,小張並不知道,他只等待最終的結果。
重定向則不同,首先小張向小李傳送請求,想讓他完成某項工作,當小李接收到這個請求時,發現自己完成不了,他立即通知小張,並推薦小王可以完成任務,於是小張又聯絡小王,最終小王完成了該項任務。

區別:
1、瀏覽器位址列顯示不同(表面區別)
無論進行多少次請求,如果使用請求轉發來實現,瀏覽器位址列中只顯示第一次傳送請求的地址;如果使用重定向來實現,瀏覽器位址列顯示的是每次請求的新地址。這只是表面上看到的不同地方。
2、元件之間可否共享資訊不同(本質區別)
從本質上講,請求轉發時,從傳送第一次到最後一次請求的過程中,WEB容器只建立一次request和response物件,請求之間始終共享這兩個物件,所以每個請求可以訪問他之前請求中的引數和屬性的值;而重定向時,瀏覽器每傳送一次請求,WEB容器都會重新建立新的request和response物件,所以請求之間不能共享資訊,即不能在請求中訪問到他之前請求中的引數和屬性的值。
3、實現方式不同

1. 請求轉發的實現步驟:

      說明將要轉發的資源;
      獲取請求轉發的物件;
      呼叫請求轉發物件中forward()方法

2. 重定向的實現步驟:

說明將要重定向的資源;
呼叫response物件中sendRedirect方法

請求轉發時轉發的過程只有WEB伺服器知道,而瀏覽器不知道進行了多少次轉發,以及都轉發給哪些元件(servlet,JSP),它只是在等待WEB伺服器最終的結果。而重定向時,每傳送一次請求,WEB伺服器都會通知瀏覽器的,所以重定向了幾次請求以及每次都向哪個元件傳送的請求,瀏覽器很清楚,當讓WEB伺服器也很明白。

【相同點】:
兩者都可以進行多次請求的轉發。

【總結】
轉發和重定向的區別

1.轉發在伺服器端完成的;重定向是在客戶端完成的
2.轉發的速度快;重定向速度慢
3.轉發的是同一次請求;重定向是兩次不同請求
4.轉發不會執行轉發後的程式碼;重定向會執行重定向之後的程式碼
5.轉發位址列沒有變化;重定向位址列有變化
6.轉發必須是在同一臺伺服器下完成;重定向可以在不同的伺服器下完成