Servlet中response对象Commit状态的分析
response是服務(wù)端對(duì)客戶端請(qǐng)求的一個(gè)響應(yīng),其中封裝了響應(yīng)頭、狀態(tài)碼、內(nèi)容(也就是最終要在瀏覽器上顯示的HTML代碼或者其他數(shù)據(jù)格式)等。
服務(wù)端在把response提交到客戶端之前,會(huì)使用一個(gè)緩沖區(qū),并向該緩沖區(qū)內(nèi)寫入響應(yīng)頭和狀態(tài)碼,然后將所有內(nèi)容flush(flush包含兩個(gè)步驟:先將緩沖區(qū)內(nèi)容發(fā)送至客戶端,然后將緩沖區(qū)清空)。
這就標(biāo)志著該次響應(yīng)已經(jīng)committed(提交)。
對(duì)于當(dāng)前頁(yè)面中已經(jīng)committed(提交)的response:
就不能再使用這個(gè)response向緩沖區(qū)寫任何東西? 。(原文這里可能有錯(cuò)誤)
不可以再進(jìn)行send***這類發(fā)送響應(yīng)內(nèi)容的操作(因?yàn)轫憫?yīng)已經(jīng)提交給客戶端),
可以使用set***這類設(shè)置響應(yīng)內(nèi)容的函數(shù)(設(shè)置后無(wú)效,因?yàn)轫憫?yīng)已經(jīng)提交給客戶端),
實(shí)測(cè)可以繼續(xù)進(jìn)行頁(yè)面內(nèi)容的輸出(--此處存疑--不能理解--實(shí)測(cè)(執(zhí)行response.getWriter().close()后會(huì)導(dǎo)致后續(xù)輸出無(wú)效,但不會(huì)爆異常)),
實(shí)測(cè)可以進(jìn)行request.getRequestDispatcher(“”).include(request, response);,
實(shí)測(cè)不可以進(jìn)行request.getRequestDispatcher(“”).forward(request, response);(會(huì)拋出IllegalStateException異常Cannot forward after response has been committed),
(注:以為JSP中,response是一個(gè)JSP頁(yè)面的內(nèi)置對(duì)象,所以同一個(gè)頁(yè)面中的response.XXX()是同一個(gè)response的不同方法,只要其中一個(gè)已經(jīng)導(dǎo)致了committed,那么其它類似方式的調(diào)用都會(huì)導(dǎo)致 IllegalStateException異常)。
導(dǎo)致 response?狀態(tài)變?yōu)?committed 的原因:
send***這類方法:向客戶端發(fā)送狀態(tài)碼或重定向會(huì)直接提交響應(yīng)。
刷新緩存:當(dāng)response對(duì)象緩存區(qū)滿時(shí),或者使用response對(duì)象的flushbuffer方法會(huì)刷新response對(duì)象的緩存導(dǎo)致響應(yīng)提交。
轉(zhuǎn)發(fā):將未提交的response通過(guò)forward轉(zhuǎn)發(fā)可能會(huì)在轉(zhuǎn)發(fā)目標(biāo)的處理流程內(nèi)被提交(include轉(zhuǎn)發(fā)不會(huì))。
forward指令和include指令很相似,它們都采用方法來(lái)導(dǎo)入目標(biāo)。
執(zhí)行forward指令時(shí),response必須未提交,目標(biāo)獲得的response與原Servlet中是同一個(gè)(ResponseFacade對(duì)象)。原先存放在response對(duì)象中的內(nèi)容將會(huì)自動(dòng)被清除,目標(biāo)可以直接發(fā)出響應(yīng),之后程序流程回到原Servlet轉(zhuǎn)發(fā)處繼續(xù)執(zhí)行,但是原Servlet似乎連頁(yè)面內(nèi)容都不可輸出了。
而執(zhí)行include指令時(shí),目標(biāo)獲得的response與原Servlet中不是同一個(gè)(被換成了一個(gè)ApplicationHttpResponse對(duì)象,讓目標(biāo)無(wú)法對(duì)源請(qǐng)求做出實(shí)質(zhì)響應(yīng),但是該對(duì)象進(jìn)行提交操作后會(huì)導(dǎo)致原Servlet中的response對(duì)象也變?yōu)橐烟峤?#xff0c;但仍然可以進(jìn)行頁(yè)面輸出)。原Servlet把目標(biāo)產(chǎn)生的響應(yīng)的內(nèi)容部分包含到自身響應(yīng)的內(nèi)容中,目標(biāo)改變響應(yīng)消息的狀態(tài)碼和響應(yīng)頭的語(yǔ)句執(zhí)行結(jié)果將被忽略(即被調(diào)用的Servlet的響應(yīng)只有內(nèi)容部分會(huì)并入原Servlet的響應(yīng)的內(nèi)容部分中)。
關(guān)于forward和include的詳細(xì)分析不在此處深究。
關(guān)于JSP中的flushBuffer
每一個(gè)JSP頁(yè)面都有一個(gè)緩沖區(qū),默認(rèn)的緩沖區(qū)大小為8KB,如果緩沖區(qū)被占滿的話,web服務(wù)器就會(huì)自動(dòng)將response 進(jìn)行commit,然后清空緩沖區(qū)(即flush)。
JSP內(nèi)置對(duì)象out相關(guān)方法:
| public abstract void?clear() throws java.io.IOException | 清除緩沖區(qū)中的內(nèi)容。如果緩沖區(qū)已經(jīng)被刷新,clear()方法將拋出IOException異常 |
| public abstract void?clearBuffer() throws java.io.IOException | 清除緩沖區(qū)中的當(dāng)前內(nèi)容。這個(gè)方法和clear()方法的區(qū)別是,如果緩沖區(qū)已經(jīng)被刷新,這個(gè)方法不會(huì)拋出IOException異常 |
| public abstract void?close() throws java.io.IOException | 刷新緩沖區(qū),關(guān)閉輸出流。注意,我們?cè)诰帉?/strong>JSP頁(yè)面時(shí),不需要顯式地去調(diào)用這個(gè)方法,因?yàn)樵贘SP容器所生成的代碼中會(huì)自動(dòng)包含對(duì)close()方法的調(diào)用。 |
| public abstract void?flush() throws java.io.IOException | 刷新緩沖區(qū),兩個(gè)步驟:1,提交response? 2.清空緩沖區(qū) |
| public int?getBufferSize() | 獲得緩沖區(qū)大小,同response.getBufferSize()相同 |
| public abstract int?getRemaining() | 獲得緩沖區(qū)中未使用的字節(jié)數(shù) |
| public boolean?isAutoFlush() | 判斷out對(duì)象是否是自動(dòng)刷新? <%@ page autoFlush="true" %> <%--Default--%> |
內(nèi)置對(duì)象response相關(guān)方法:
| response.isCommitted() | 確認(rèn)response是否已經(jīng)committed |
| response.flushbuffer(); | 同out.flush相同 |
增大緩沖區(qū)大小:
?
| <%@ page buffer="10kb" %> |
?文參考:https://www.cnblogs.com/ismallboy/p/6785328.html
轉(zhuǎn)載于:https://www.cnblogs.com/Leroscox/p/8305141.html
總結(jié)
以上是生活随笔為你收集整理的Servlet中response对象Commit状态的分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Microsoft Power BI D
- 下一篇: set 与 map 的第一次尝试