getOutputStream() has already been called for this response 這個(gè)錯(cuò)誤遇到過不少次,網(wǎng)上看到大多不能解決問題。
下面兩點(diǎn)是我自己總結(jié)出來的:
1、在我們應(yīng)用驗(yàn)證碼時(shí),都會(huì)用到字節(jié)流response.getOutputStream()來將驗(yàn)證碼輸出,但是jsp頁(yè)面自己最后會(huì)調(diào)用字符流JspWriter的out()方法將頁(yè)面的內(nèi)容輸出。通過查看servlet的API我們可以看到知道,在servlet中不能夠同時(shí)利用這兩個(gè)流輸出,解決辦法將驗(yàn)證碼寫在servlet中,具體見下面。
2、相信請(qǐng)求轉(zhuǎn)發(fā)( request.getRequestDispacher().forward() )和請(qǐng)求跳轉(zhuǎn)( response.sendRedirect() )的區(qū)別大家都知道。其中request.getRequestDispacher().forward() 方法的調(diào)用者與被調(diào)用者之間共享相同的request對(duì)象和response對(duì)象,它們屬于同一個(gè)訪問請(qǐng)求和響應(yīng)過程。JSP頁(yè)面轉(zhuǎn)譯為的_servlet會(huì)最后調(diào)用releasePageContext()方法( All PageContext objects obtained via this method shall be released by invoking releasePageContext().)釋放我們頁(yè)面所有的實(shí)體對(duì)象,當(dāng)我們的調(diào)用者有頁(yè)面輸出時(shí),就會(huì)拋出這個(gè)異常。具體原因也沒有弄清楚,各位大俠如果誰(shuí)知道可以告知一下。其實(shí)驗(yàn)證碼也是同一個(gè)原理,如果我們將驗(yàn)證碼的代碼寫在jsp頁(yè)面中,因?yàn)閖sp頁(yè)面會(huì)調(diào)用JspWriter的out()方法將內(nèi)容輸出,同時(shí)我們的圖片又調(diào)用了response.getOutputStream()方法因此會(huì)拋出這個(gè)異常;如果我們將驗(yàn)證碼寫在servlet中,就不會(huì)同時(shí)使用兩種輸出也就不會(huì)出錯(cuò)。有時(shí)即使調(diào)用者頁(yè)面沒有輸出,也會(huì)拋出這個(gè)異常,仔細(xì)看jsp轉(zhuǎn)譯以后的源碼發(fā)現(xiàn)輸出了換行,因此,我們最好把調(diào)用者頁(yè)面的%>和<%之間換行去掉,把%>和<%直接寫在一起。
另外,如果我們實(shí)在要在jsp中用到response.getOutputStream(),比如驗(yàn)證碼、jspSmartUpload,我們需要在最后加入如下代碼:
response.reset();
out.clear();
out=pageContext.pushBody();
有不對(duì)之處還望指教!
下面兩點(diǎn)是我自己總結(jié)出來的:
1、在我們應(yīng)用驗(yàn)證碼時(shí),都會(huì)用到字節(jié)流response.getOutputStream()來將驗(yàn)證碼輸出,但是jsp頁(yè)面自己最后會(huì)調(diào)用字符流JspWriter的out()方法將頁(yè)面的內(nèi)容輸出。通過查看servlet的API我們可以看到知道,在servlet中不能夠同時(shí)利用這兩個(gè)流輸出,解決辦法將驗(yàn)證碼寫在servlet中,具體見下面。
2、相信請(qǐng)求轉(zhuǎn)發(fā)( request.getRequestDispacher().forward() )和請(qǐng)求跳轉(zhuǎn)( response.sendRedirect() )的區(qū)別大家都知道。其中request.getRequestDispacher().forward() 方法的調(diào)用者與被調(diào)用者之間共享相同的request對(duì)象和response對(duì)象,它們屬于同一個(gè)訪問請(qǐng)求和響應(yīng)過程。JSP頁(yè)面轉(zhuǎn)譯為的_servlet會(huì)最后調(diào)用releasePageContext()方法( All PageContext objects obtained via this method shall be released by invoking releasePageContext().)釋放我們頁(yè)面所有的實(shí)體對(duì)象,當(dāng)我們的調(diào)用者有頁(yè)面輸出時(shí),就會(huì)拋出這個(gè)異常。具體原因也沒有弄清楚,各位大俠如果誰(shuí)知道可以告知一下。其實(shí)驗(yàn)證碼也是同一個(gè)原理,如果我們將驗(yàn)證碼的代碼寫在jsp頁(yè)面中,因?yàn)閖sp頁(yè)面會(huì)調(diào)用JspWriter的out()方法將內(nèi)容輸出,同時(shí)我們的圖片又調(diào)用了response.getOutputStream()方法因此會(huì)拋出這個(gè)異常;如果我們將驗(yàn)證碼寫在servlet中,就不會(huì)同時(shí)使用兩種輸出也就不會(huì)出錯(cuò)。有時(shí)即使調(diào)用者頁(yè)面沒有輸出,也會(huì)拋出這個(gè)異常,仔細(xì)看jsp轉(zhuǎn)譯以后的源碼發(fā)現(xiàn)輸出了換行,因此,我們最好把調(diào)用者頁(yè)面的%>和<%之間換行去掉,把%>和<%直接寫在一起。
另外,如果我們實(shí)在要在jsp中用到response.getOutputStream(),比如驗(yàn)證碼、jspSmartUpload,我們需要在最后加入如下代碼:
response.reset();
out.clear();
out=pageContext.pushBody();
有不對(duì)之處還望指教!