同時呼叫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.轉發必須是在同一臺伺服器下完成;重定向可以在不同的伺服器下完成