1. 程式人生 > >response細節--重定向的用處和getWrite/getOutputStream的用法衝突問題

response細節--重定向的用處和getWrite/getOutputStream的用法衝突問題

1.重定向的實現:
//和下句程式碼可互換位置,此兩行相當於response.sendRedirect("");
    response.setStatus(302);
    //或者"location.jsp"
    response.setHeader("location","/HTTPHeader/location.jsp");
2.重定向的用處:

   一般情況下儘量不要用重定向,因為其會向伺服器傳送兩次請求,增加伺服器的負荷,並且會產生兩個request和response對,除了特殊的場合:如:

    (1)使用者登入成功後跳轉至首頁,如果用轉發的話,那麼使用者無法從位址列上看到首頁地址

    (2)購物時,點選"加入購物車"按鈕,然後就轉向“顯示購物車商品的頁面showCar.jsp”,如果使用轉發技術的,那麼在“showCar.jsp”頁面上如果重新整理頁面的話,則就會將“加入購物車的事件在作一次”。

    (3)在表單提交後(get和post方式都是一樣),如果想跳轉至某頁面,如果用轉發的話,則轉至頁面後,如果重新整理頁面,則會造成表單重複提交:

如:當提交以post方式的表單後,如果重新整理頁面:


當點選重試後:


提交表單後,如果改為重定向到該頁面,則重新整理頁面也只是重新整理該頁面,而不會造成表單重複提交

3. getOutputStream和getWriter互斥問題:

     這兩個方法互相排斥,呼叫了其中的任何一個方法後,就不能再呼叫另一方法。

    如:ExpiresServlet:

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
        //設定快取時間為1小時:時間單位為毫秒
		 response.setDateHeader("Expires", System.currentTimeMillis()+1000*3600);
		 String data = "abcdefghigk";
		 //response.getWriter().print(data);
		 response.getOutputStream().write(data.getBytes());
		 //jsp中是也PrintWriter物件輸出內容的
		 request.getRequestDispatcher("index.jsp").forward(request, response);//改為response.sendRedirect("index.jsp");則不會拋該異常
	}
如果訪問該Servlet,則會丟擲:java.lang.IllegalStateException: getOutputStream() has already been called for this response 異常


這說明同一個response物件的這兩個方法互相排斥,呼叫了其中的任何一個方法後,就不能再呼叫另一方法。

解決辦法:將request.getRequestDispatcher("index.jsp").forward(request, response);//改為response.sendRedirect("index.jsp");則不會拋該異常

原因分析:改為重定向後,則 是兩個response物件

4.其他問題:

   (1)getOutputStream和getWriter方法分別用於得到輸出二進位制資料、輸出文字資料的ServletOuputStream、Printwriter物件。
   (2)getOutputStream和getWriter這兩個方法互相排斥,呼叫了其中的任何一個方法後,就不能再呼叫另一方法。  
   (3)Servlet程式向ServletOutputStream或PrintWriter物件中寫入的資料將被Servlet引擎從response裡面獲取,Servlet引擎將這些資料當作響應訊息的正文,然後再與響應狀態行和各響應頭組合後輸出到客戶端。
   (4)Serlvet的service方法結束後,Servlet引擎將檢查getWriter或getOutputStream方法返回的輸出流物件是否已經呼叫過close方法,如果沒有,Servlet引擎將呼叫close方法關閉該輸出流物件