[英]java.lang.IllegalStateException: getOutputStream() has already been called for this response
[英]java.lang.IllegalStateException: getOutputStream() has already been called for this response
當我嘗試從客戶端請求從服務器加載圖像時,我收到以下異常:
241132533 [TP-Processor1]錯誤[/jspapps].[jsp] - 用於servlet jsp的Servlet.service()拋出異常java.lang.IllegalStateException:已經為此響應調用了getOutputStream()
任何人都可以向我解釋這個例外以及如何克服它嗎?
任何人都可以向我解釋這個例外
您正在嘗試使用JSP文件中的原始Java代碼將二進制數據寫入response.getOutputStream()
該文件本身已使用response.getWriter()
來編寫任何模板文本。 另請參閱鏈接的javadocs的Throws部分。
以及如何克服它?
而是在真正的Java類中編寫Java代碼。 創建一個extends
HttpServlet
的類,將所有Java代碼移動到那里,將其映射到web.xml
並更改請求URL以調用servlet。
我只是偶然發現了這個老問題,因為我有同樣的問題。 最后,很容易擺脫異常:只需在之前調用out.clear()
:
out.clear();
...
// later, in a different method
ServletOutputStream out = response.getOutputStream();
...
out.clear()
還幫我擺脫了<%@page import=...
等所有空行。
確保消除view_image.jsp
所有輸出。 簡單的換行符可以負責生成輸出。
例如,如果你有這些聲明......
<%@ page import ... %>
<%@ page import ... %>
......你應該這樣寫
<%@ page import ... %><%@ page import ... %><%
...%>
如果您查看已編譯的servlet代碼,則在圖像響應之前不應該看到out.write("\\r\\n")
。
更好的方法是將view_image.jsp
更改為Servlet,但如果不能這樣做,刪除jsp中的換行符就是一種解決方法。
<%@page import="java.sql.DriverManager"%>
<%@page import="java.io.InputStream"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%
Connection con=null;
ResultSet rs = null;
Statement st = null;
String sql = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("test","root","root");
st = con.createStatement();
sql = "select image from projects where projectid='1'";
System.out.println(sql);
rs = st.executeQuery(sql);
String imgLen = "";
out.clear();
while (rs.next())
{
imgLen = rs.getString(1);
System.out.println(imgLen.length());
int len = imgLen.length();
byte[] rb = new byte[len];
InputStream readImg = rs.getBinaryStream(1);
int index = readImg.read(rb, 0, len);
response.reset();
response.setContentType("image/jpg");
response.getOutputStream().write(rb, 0, len);
response.getOutputStream().flush();
response.getOutputStream().close();
}
st.close();
rs.close();
if (true) return;
} catch (Exception e) {e.printStackTrace();}
%>
試試這個,它不是最好的解決方案,但它的工作原理。
in.close();
out2.flush();
out.clear();
out = pageContext.pushBody();
其中'in'是InputStream(如果你正在使用它),'out2'是新的response.getOutputStream()
,'out'是默認的JspWriter
。
我剛剛在最近的工作中遇到了同樣的問題。
我們有一個servlet過濾器,我們在其中使用ServletResponse.getWriter()方法來編寫主體,在一些Spring MVC控制器中,我們還使用response.getOutputStream()將類似圖像(字節數組)的內容寫入正文。
由於每個請求都將通過過濾器,並基於Java API doc:
“可以調用此方法(getWriter())或getOutputStream()來編寫正文,而不是兩者。”
這就是我們得到“java.lang.IllegalStateException:getOutputStream()已被調用此響應”異常的原因。
所以在那個過濾器中,我將代碼更改為:
ServletOutputStream sos = response.getOutputStream();
sos.write(newHtml.getBytes("UTF8")); // newHtml is a String.
sos.flush();
它為我解決了這個問題。
將view_image.jsp轉換為映射到ViewImage
的Servlet並調用它
<img src='<%= request.getContextPath() %>/ViewImage?pat_acc=<%=Pat_Acct%>' style='position: absolute; left: 0pt; top: 0px;' "/>
在您的JSP文件中。
嘗試從jsp文件中刪除所有模板文本。 例如,
1 <%@
2 ....
3 %>
4 <%
5 ....
6 %>
在第3行和第4行之間有一個'\\ n',它被視為模板文本,調用response.getWriter()將'\\ n'寫入客戶端。 在第6行之后,也可能存在不可見的空格,這會使輸出流搞砸。 但是第5行可以提前return
以避免這種情況。
在Spring中,您可以解決此問題的變化
response.getOutputStream().write(cabecera.getBytes());
至
response.getWriter().write(cabecera);
我有這個代碼並修改如下:
@RequestMapping(value = "xyz", method = RequestMethod.POST)
public String generateReport(HttpServletResponse response, @Valid @ModelAttribute Form form, Errors errors, Model model) {
if (errors.hasErrors()) {
model.addAttribute(form);
return "abcd/xyz";
} else {
someMethodWhichUsesResponse(response);
}
Earlier:
return "abcd/xyz";
Fixed by:
return null;
}
我返回null,因為從這種方法,我期待下載。 根據這里給出的解釋,我解決了我的問題。
如果您在servlet中遇到此問題,那么在從servlet向瀏覽器發送響應時:
PrintWriter out=response.getWriter();
這應該是您可以在servlet中編寫最終發送到瀏覽器的html代碼的第一個語句
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.