深刻體驗JavaWeb開發內幕之Response對象html
當客戶端向服務器發出請求時,服務端經過request對象接收到請求內容並經過response對象向Web容器返回響應信息,所以response對象是十分重要的。java
下面咱們來看一下關於response對象的相關內容:編程
簡介數組
Web服務器收到客戶端的http請求,會針對每一次請求,分別建立一個用於表明請求的request對象、和表明響應的response對象。瀏覽器
request對象和response對象既然分別表明請求和響應,那咱們要獲取客戶端提交過來的數據,只須要找request對象就好了。要向客戶端輸出數據,只須要找response對象就好了。緩存
HttpServletResponse簡介服務器
WEB服務器回送給WEB客戶端的HTTP響應消息分爲三個部分:ui
①狀態行(對應請求行)(兩者統稱爲開始行)編碼
②消息報頭 url
(空白行)(或者叫空行)
③響應正文(也叫實體內容)(對應請求正文) (兩者統稱爲消息正文)
ServletAPI中定義的ServletResponse接口類用於建立響應消息。
HttpServletResponse是專用於HTTP協議的ServletResponse子接口,它用於封裝HTTP響應消息。
HttpServletResponse定義了一系列用於描述各類HTTP狀態碼的常量。
在service()方法內部調用HttpServletResponse對象的各類方法來建立響應消息。
產生響應狀態行
HTTP響應消息的響應狀態行包括HTTP版本、狀態代碼和一條相關的提示信息:
HTTP/1.1 200 OK
HttpServletResponse中定義了若干與狀態碼數值對應的常量,每一個常量的名稱之前綴SC(Status Code的簡寫)開頭,而後是狀態碼在HTTP 1.1規範中所表示的狀態信息的英文單詞的組合,每一個單詞之間用下劃線鏈接,且全部字母都大寫。
狀態碼404 對應的常量爲HttpServletResponse.SC_NOT_FOUND
setStatus方法用於設置HTTP響應消息的狀態碼,並生成響應狀態行。
sendError方法用於發送表示錯誤信息的狀態碼(通常是404,找不到客戶機所請求的資源)到客戶端,並清除緩衝區中的內容。
構建響應消息頭
操做消息頭的相關方法:
addHeader與setHeader方法
addIntHeader與setIntHeader方法
addDateHeader與setDateHeader方法
setContentLength方法
setContentType方法:用於設置Servlet輸出內容的MIME類型,對於HTTP協議來講,就是設置Content-Type響應頭字段的值。如「text/html;charset=UTF-8」。
setCharacterEncoding方法:用於設置輸出內容的MIME聲明中的字符集編碼,對HTTP協議來講,就是設置Content-Type頭字段中的字符編碼部分。
HttpServletResponse對象服務器的響應。這個對象中封裝了向客戶端發送數據、發送響應頭、發送響應狀態碼的方法。
response常見應用
向客戶端輸出中文數據
• 分別以OutputStream和PrintWriter(屬於第⑤種:Print流)輸出
• 多學一招:使用HTML語言裏面的<meta>標籤來控制瀏覽器行爲
• 思考:用OutputStream輸出1,爲何用戶看到的不是1?
文件下載和中文文件的下載
輸出隨機圖片
發送http頭,控制瀏覽器定時刷新網頁(REFRESH)。
發送http頭,控制瀏覽器禁止緩存當前文檔內容。
Servlet的中文輸出問題——原理
瀏覽器接收到的中文字符並非中文符號自己(廢話),而是它的某種字符集編碼的數據。
瀏覽器必須使用正確的字符集編碼進行查看,才能將它所接收到的數據顯示爲正確的中文字符。
當Servlet程序僅僅須要輸出純文本格式的響應正文時,一般應調用ServletResponse對象的getWriter方法返回一個PrintWriter(屬於第⑤種:Print流)對象,而後使用這個PrintWriter對象將文本內容寫入到客戶端。
Java程序中的字符文本在內存中是以Unicode編碼的形式存在的,PrintWriter對象在輸出字符文本時,須要先將它們轉換成其餘某種字符集編碼的字節數組(char[] ch)後輸出。
ServletResponse對象的getWriter方法返回的PrintWriter對象默認使用ISO8859-1字符集編碼進行Unicode字符串到字節數組的轉換,因爲ISO8859-1字符集中根本就沒有中文字符,Unicode編碼的中文字符將被轉換成無效的字符編碼後輸出給客戶端。
Servlet的中文輸出問題——解決辦法
ServletResponse接口中定義了setCharacterEncoding、setContentType等方法來指定ServletResponse.getWriter方法返回的PrintWriter(屬於第⑤種:Print流)對象所使用的字符集編碼。
調用ServletResponse接口中定義的setContentType方法,在HTTP響應消息的Content-Type頭字段中指定響應正文的字符集編碼。
使用<meta>標籤模擬響應消息頭
問題:
利用HTTP消息的響應頭字段,可讓瀏覽器完成各類有用的功能。可是,這須要經過編寫Web服務器端的程序來實現。若是不會服務器端編程的普通HTML頁面製做者也想借助HTTP消息的響應頭字段來實現一些特殊功能,他們該怎麼辦呢?
解決方案:
HTML語言中專門定義了<meta>標籤的http-equiv屬性來在HTML文檔中模擬HTTP響應消息頭,當瀏覽器讀取到 HTML文檔中具備http-equiv屬性的<meta>標籤時,它會用與處理WEB服務器發送的響應消息頭同樣的方式來進行處理。
舉例:
<metahttp-equiv="Expires" content="0"> <metahttp-equiv="Cache-Control" content="no-cache"> <metahttp-equiv="Pragma" content="no-cache"> <metahttp-equiv="Refresh"content="0;url=http://www.it315.org"> <meta http-equiv="Content-Type"content="text/html; charset=GB2312">
如何實現動態文件內容的下載
須要經過HttpServletResponse.setHeader方法設置Content-Disposition頭的值爲「attachment; filename =文件名」。
應該調用HttpServletResponse.getOutputStream方法返回的ServletOutputStream對象來向客戶 端寫入附件文件內容,而不該使用HttpServletResponse.getWriter方法返回的PrintWriter對象。
經過response對象實現請求重定向。
請求重定向指:一個Web資源收到客戶端請求後,通知客戶端去訪問另一個Web資源,這稱之爲請求重定向。
應用場景:用戶登陸。
實現方式
• response.sendRedirect()
• 實現原理:
• 302狀態碼和location頭便可實現重定向
response細節
getOutputStream和getWriter方法分別用於獲取輸出二進制數據、輸出文本數據的ServletOuputStream、Printwriter對象。
getOutputStream和getWriter這兩個方法互相排斥,調用了其中的任何一個方法後,就不能再調用另外一方法。
Servlet程序向ServletOutputStream或PrintWriter對象中寫入的數據將被Servlet引擎從response裏面獲取,Servlet引擎將這些數據看成響應消息的正文,而後再與響應狀態行和各響應頭組合後輸出到客戶端。
Serlvet的service方法結束後,Servlet引擎將檢查getWriter或getOutputStream方法返回的輸出流對象是否已經調用過close方法,若是沒有,Servlet引擎將調用close方法關閉該輸出流對象。