簡體   English   中英

java.lang.IllegalStateException:已為此響應調用了getOutputStream()

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM