Servlet的學習(九)

來源:互聯網
上載者:User

標籤:

  本篇來說明響應對象HttpServletResponse對象的最後一點內容。

  首先來看響應對象控制瀏覽器定時重新整理,在我的web應用【myservlet】中建立Servlet,在該Servlet中設定回應標頭,定時重新整理的代碼很簡單:

response.setHeader("refresh", "3 ");    //3秒重新整理一次

就可告知瀏覽器3秒重新整理一次網頁。當然“Refresh”回應標頭還是可以定時跳轉到指定頁面,如下代碼:

response.setHeader("refresh", "3;url=‘/myservlet/index.jsp‘");

將會在訪問我這個Servlet的3秒後訪問我的【myservlet】web應用下的index.jsp資源。

 

  之前說過,使用<meta>標籤可以類比回應標頭,同樣在這裡可以使用Servlet向用戶端寫資料時將<meta>標籤寫入響應資料實體,由瀏覽器解析後再來控制:

1 String data = "銀魂";2 response.setContentType("text/html;charset=UTF-8");3 response.getWriter().write("<meta http-equiv=‘refresh‘ content=‘3;url=/myservlet/index.jsp‘ >");4 response.getWriter().write(data);

 

  這裡請注意:在向響應對象寫入任何資料之前,請先設定好使用的編碼錶,如果在寫入資料之後再設定編碼錶則無效,例如下面代碼:

1 String data = "銀魂";2 response.getWriter().write(data);3 response.setContentType("text/html;charset=UTF-8");

通過查看HttpWathch可以知道,編碼錶並沒有設定成功:

  

把設定編碼錶的代碼放置在向響應對象寫入資料也是不行的,如下:

1 String data = "銀魂";2 response.getWriter().write("<meta http-equiv=‘refresh‘ content=‘3;url=/myservlet/index.jsp‘ >");3 response.setContentType("text/html;charset=UTF-8");4 response.getWriter().write(data);

這樣也會設定編碼錶無效,造成中文亂碼問題,所以在向響應對象寫入任何資料之前請確保先將編碼錶設定好。

 

  請求重新導向:之前在http協議中學習了響應碼302和“Location”回應標頭可以佈建要求重新導向。

一個簡單的程式碼範例(web工程名為【myservlet】):

1   response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);  //302狀態代碼2   response.setHeader("location", "/myservlet/index.jsp");

對於不太熟悉HTTP協議的編程人員來說,當然還有更快捷的方式:

1 response.sendRedirect("/myservlet/index.jsp");

驗證:在瀏覽器中的地址欄中鍵入該Servlet的地址,瀏覽器則是會跳轉至該web目錄下的index.jsp,這個可以從瀏覽器地址欄上看出。

  關於請求重新導向中的細節:

  一次請求重新導向會向伺服器發送兩次請求。也就是說會產生兩次response響應對象和request請求對象;同時瀏覽器的地址欄是會發生變化的,URL將跳轉到重新導向後的頁面地址。這點和轉寄不同(在《Servlet的學習(五)》中說過)。

 

  最後再回到response響應對象的getOutputStream方法和getWriter方法,這兩個方法在《Servlet的學習(七)》中已經詳細介紹瞭解決中文亂碼問題,那麼現在我們還需要注意的是:getOutputStream方法和getWriter方法這兩個方法相互排斥,不能同時使用。否則會出現如下問題:

  

也許大家會瞧不起這個問題,認為不就是在一個Servlet中不要同時使用位元組流和字元流嘛,注意下就好了。

  問題當然不會這麼簡單,比如在轉寄中使用不同的IO流還是會出現這種問題的:

  假設我的【myservlet】這個web工程中有兩個Servlet:ServletResponse1和ServletResponse2。

在ServletResponse1中的代碼為:

1     response.getWriter();2     RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/WEB-INF/classes/ServletResponse2");3     dispatcher.forward(request, response);

在ServletResponse2中的代碼為:

1     response.getOutputStream();

那麼結果是直接部署出錯:

  

在ServletResponse1中將Response對象傳遞給ServletResponse2中,本身Response就已經調用了擷取Writer對象的方法,因此不能再在ServletResponse2中擷取OutputStream對象,所以在做轉寄時要特別注意獲得IO流對象。

 

  而將Servlet調用getOutputStream()方法後再轉寄給JSP檔案也是會出錯的

比如在ServletResponse1中代碼為:

1     OutputStream out = response.getOutputStream();2     RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/index.jsp");3     dispatcher.forward(request, response);

而訪問這個Servlet會看到:

  

這是因為在Servlet向JSP中寫入資料時預設使用了getWriter()方法擷取字元流,然後向JSP中寫入資料,這時如果我們在轉寄JSP之前的Servlet再使用getOutputStream必然會產生衝突。如果想向JSP中傳入的必須是使用位元組流才能傳輸的資料,請查驗相關解決方案。

 

Servlet的學習(九)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.