servlet–response、request
- 2019 年 10 月 10 日
- 筆記
請求響應流程圖

- response 1 response概述 response是Servlet.service方法的一個參數,類型為javax.servlet.http.HttpServletResponse。在客戶端發出每個請求時,伺服器都會創建一個response對象,並傳入給Servlet.service()方法。response對象是用來對客戶端進行響應的,這說明在service()方法中使用response對象可以完成對客戶端的響應工作。 response對象的功能分為以下四種: l 設置響應頭資訊; l 發送狀態碼; l 設置響應正文; l 重定向; 2 response響應正文 response是響應對象,向客戶端輸出響應正文(響應體)可以使用response的響應流,repsonse一共提供了兩個響應流對象: l PrintWriter out = response.getWriter():獲取字元流; l ServletOutputStream out = response.getOutputStream():獲取位元組流; 當然,如果響應正文內容為字元,那麼使用response.getWriter(),如果響應內容是位元組,例如下載時,那麼可以使用response.getOutputStream()。 注意,在一個請求中,不能同時使用這兩個流!也就是說,要麼你使用repsonse.getWriter(),要麼使用response.getOutputStream(),但不能同時使用這兩個流。不然會拋出IllegalStateException異常。 2.1 字元響應流 l 字元編碼 在使用response.getWriter()時需要注意默認字元編碼為ISO-8859-1,如果希望設置字元流的字元編碼為utf-8,可以使用response.setCharaceterEncoding(「utf-8」)來設置。這樣可以保證輸出給客戶端的字元都是使用UTF-8編碼的! 但客戶端瀏覽器並不知道響應數據是什麼編碼的!如果希望通知客戶端使用UTF-8來解讀響應數據,那麼還是使用response.setContentType("text/html;charset=utf-8")方法比較好,因為這個方法不只會調用response.setCharaceterEncoding(「utf-8」),還會設置content-type響應頭,客戶端瀏覽器會使用content-type頭來解讀響應數據。 l 緩衝區 response.getWriter()是PrintWriter類型,所以它有緩衝區,緩衝區的默認大小為8KB。也就是說,在響應數據沒有輸出8KB之前,數據都是存放在緩衝區中,而不會立刻發送到客戶端。當Servlet執行結束後,伺服器才會去刷新流,使緩衝區中的數據發送到客戶端。 如果希望響應數據馬上發送給客戶端:
- 向流中寫入大於8KB的數據;
- 調用response.flushBuffer()方法來手動刷新緩衝區;
/* String s = "Hello outputStream"; byte[] bytes = s.getBytes(); response.getOutputStream().write(bytes); */ /** * 演示響應位元組數據 */ // 把一張圖片讀取到位元組數組中 String path = "F:/F/白冰.jpg"; FileInputStream in = new FileInputStream(path); // byte[] bytes = IOUtils.toByteArray(in);//讀取輸入流內容的位元組到位元組數組中。 // response.getOutputStream().write(bytes); IOUtils.copy(in, response.getOutputStream()); 3 設置響應頭資訊 可以使用response對象的setHeader()方法來設置響應頭!使用該方法設置的響應頭最終會發送給客戶端瀏覽器! l response.setHeader(「content-type」, 「text/html;charset=utf-8」):設置content-type響應頭,該頭的作用是告訴瀏覽器響應內容為html類型,編碼為utf-8。而且同時會設置response的字元流編碼為utf-8,即response.setCharaceterEncoding(「utf-8」); l response.setHeader("Refresh","5; URL=http://www.itcast.cn"):5秒後自動跳轉到傳智主頁。 /* * 下面是用來發送響應體! */ PrintWriter writer = response.getWriter(); writer.print("歡迎XXX登錄!5秒鐘後會自動跳轉到主頁!您看到的一定是亂碼!"); /* * 設置名為Refresh的響應頭 */ response.setHeader("Refresh", "5;URL=/day10_1/EServlet"); 4 設置狀態碼及其他方法 l response.setContentType("text/html;charset=utf-8"):等同與調用response.setHeader(「content-type」, 「text/html;charset=utf-8」); l response.setCharacterEncoding(「utf-8」):設置字元響應流的字元編碼為utf-8; l response.setStatus(200):設置狀態碼; l response.sendError(404, 「您要查找的資源不存在」):當發送錯誤狀態碼時,Tomcat會跳轉到固定的錯誤頁面去,但可以顯示錯誤資訊。 5 重定向 5.1 什麼是重定向 當你訪問http://www.sun.com時,你會發現瀏覽器地址欄中的URL會變成http://www.oracle.com/us/sun/index.htm,這就是重定向了。 重定向是伺服器通知瀏覽器去訪問另一個地址,即再發出另一個請求。

/* * 重定向: * 1. 設置Location * 2. 發送302狀態碼 */ // response.setHeader("Location", "/day10_1/CServlet"); // response.setStatus(302); //快捷的重定向方法 response.sendRedirect("/day10_1/CServlet");
5.2 完成重定向
響應碼為200表示響應成功,而響應碼為302表示重定向。所以完成重定向的第一步就是設置響應碼為302。
因為重定向是通知瀏覽器再第二個請求,所以瀏覽器需要知道第二個請求的URL,所以完成重定向的第二步是設置Location頭,指定第二個請求的URL地址。
public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setStatus(302);[崔1] response.setHeader("Location", "http://www.itcast.cn");[崔2] } } |
---|
上面程式碼的作用是:當訪問AServlet後,會通知瀏覽器重定向到傳智主頁。客戶端瀏覽器解析到響應碼為302後,就知道伺服器讓它重定向,所以它會馬上獲取響應頭Location,然發出第二個請求。
5.3 便捷的重定向方式
public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendRedirect("http://www.itcast.cn"); } } |
---|
response.sendRedirect()方法會設置響應頭為302,以設置Location響應頭。
如果要重定向的URL是在同一個伺服器內,那麼可以使用相對路徑,例如:
public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendRedirect("/hello/BServlet"); } } |
---|
重定向的URL地址為:http://localhost:8080/hello/BServlet。
5.4 重定向小結
l 重定向是兩次請求;
l 重定向的URL可以是其他應用,不局限於當前應用;
l 重定向的響應頭為302,並且必須要有Location響應頭;
l 重定向就不要再使用response.getWriter()或response.getOutputStream()輸出數據,不然可能會出現異常;
[崔1]設置響應碼為302,表示重定向
[崔2]設置新請求的URL