Servlet4.0 Response對象Response對象封裝Server返回Client的所有信息。在HTTP協議中,Server傳達給Client信息轉換到HTTP Header或者HTTP BODY中。5.1 Buffering緩衝區Serverlet Container可以但不強制緩衝發 ...
Servlet4.0 Response對象
Response對象封裝Server返回Client的所有信息。在HTTP協議中,Server傳達給Client信息轉換到HTTP Header或者HTTP BODY中。
5.1 Buffering緩衝區
Serverlet Container可以但不強制緩衝發送給客戶端的內容。預設得,Servlet Container會開放介面設置緩衝區。如ServletResponse對象的方法可以設置緩衝區:
- getBufferSize
- setBufferSize
- isCommitted
- reset
- resetBuffer
- flushBuffer
當Servlet Container使用ServletOutputStream或者Write時,可以使用這些方法配置緩衝區。
getBufferSize返回緩衝區大小,若沒有緩衝區,則返回0。
setBufferSize servlet可以使用該方法設置緩衝區大小。
申請的大小可以不是servlet請求的大小,但是至少要是請求的大小。這樣,容器才能重使用該緩衝區,也能夠提供足夠的緩衝區。該方法需要在Servlet Container使用ServletOutputStream或者是Writer輸出響應之前調用。
isCommitted方法表示內容是否已經響應給客戶端。
flushBuffer方法強制將緩衝區數據輸出至客戶端。
reset方法強制清空緩衝區的數據若內容未提交至客戶端。
resetBuffer方法強制清空緩衝區的數據但不包括請求頭和響應碼若內容未提交至客戶端。
若內容已經輸出至客戶端,調用reset方法或resetBuffer方法都會拋出異常。但是不會改變緩衝區內容。
若緩衝區已經滿需要立即輸出響應內容給客戶端。
5.2 HTTP響應頭
Servlet可以通過ServletResponse介面的方法設置HTTP響應頭。方法如下:
- setHeader
- addHeader
setHeader使用指定的名稱替換已經存在的值,若header的值是集合,則集合的值被清空,使用新值替換。
addHeader添加指定名稱的值到集合,該名稱未存在,則會創建新集合。
若header的值是int類型或Date類型,則ServletResponse介面提供下述方法:
- setIntHeader
- setDateHeader
- addIntHeader
- setIntHeader
HTTP響應頭需要比響應體輸出至客戶端,若響應體已經輸出再輸出響應頭,Servlet Container會忽略響應頭。
對於Servlet生成的內容Servlet 編程者有義務設置Content-Type。HTTP/1.1不要求必須設置Content-Type請求頭。
推薦Servlet Container 使用X-Powerd-By請求頭髮布自身的實現。
這個請求頭的值起碼是一個以上。如"Servlet/4.0"。
5.3 HTTP Trailer 預告
HTTP Trailer是發送在響應體之後的響應頭集合。適用於chunked編碼發送的場景或者是其他額外的協議。
如果HTTP Trailer 請求頭已經就緒則調用isTrailerFieldsReady()方法會返回true。
servlet可以通過HttpServletRequest介面的getTrailerFields()方法讀取 Trailer 請求頭。
servlet可以輸出HTTP Trailer頭通過提供Supplier給HttpServletResponse介面提供的setTrailerFields()方法。也可以通過提供的Supplier使用HttpServletResponse介面的getTrailerFields()方法獲取HTTP Trailer請求頭。
5.4 非阻塞IO
非阻塞IO只能在非同步處理請求中使用。否則ServletInputStream.setReadListener和ServletOutputStream.setWriteListener調用時,需要拋出IllegalStateException異常。
為了支持在Web 容器支持非阻塞寫,引入如下改變:
WriteListener提供下述回調方法:
- void onWritePossible() 當WriteListener註冊到ServletOutputStream
後,當ServletOutputStream能寫時會第一次調用WriteListener.onWritePossible()方法。
只有當ServletOutputStream.isReady()方法返回true才會調用WriteListener.onWritePossible()方法。
- onError(Throwable t)處理響應失敗時會調用該方法。
伴隨著WriteListener還有ServletOutputStream的其他方法幫助WebApplication判斷是否準備好寫內容至客戶端。
- boolean isReady()如果寫ServletOutputStream成功則會返回true。如果這個方法返回true,則ServletOutputStream寫操作可以繼續完成。若沒有後續內容需要寫,則該方法返回false。
- void setWriteListener(WriteListener listener) 關聯WriteListener和ServletOutputStream。當可以寫入數據時容器會調用WriteListener的方法。
註冊的WriteListener會開始非阻塞IO,此時禁止轉為阻塞IO。Servlet Container需要保證WriteListener的線程安全
5.5 Response對象的生命周期
每個Response對象都只能在service或者doFilter方法中生效,非同步處理請求除外。
非同步處理請求情況下,Response對象一直有效直到Servlet Container 調用AsyncContext.complete方法後。Servlet Container會回收Response對象為了提供性能,
研發需要明白,在這些作用域外引用Response對象都會引發未知錯誤。