java.lang.IllegalStateException:已为此响应调用了getOutputStream()

时间:2010-08-22 06:32:22

标签: java jsp

当我尝试请求从客户端的服务器加载图像时,我收到以下异常:

  

241132533 [TP-Processor1] ERROR [/jspapps].[jsp] - servlet jsp的Servlet.service()抛出异常   java.lang.IllegalStateException:已为此响应调用了getOutputStream()

任何人都可以向我解释这个例外以及如何克服它吗?

11 个答案:

答案 0 :(得分:7)

  

任何人都可以向我解释这个例外

您正在尝试使用JSP文件中的原始Java代码将二进制数据写入response.getOutputStream(),该文件本身已使用response.getWriter()来编写任何模板文本。另请参阅链接的javadocs的投掷部分。

  

还有如何克服它?

将Java代码写入真正的Java类中。创建一个extends HttpServlet的类,将所有Java代码移到那里,将其映射到web.xml并更改请求URL以调用servlet。

另见:

答案 1 :(得分:6)

我偶然发现了这个老问题,因为我有同样的问题。最后,很容易摆脱异常:只需在out.clear()之前调用:

out.clear();
...
// later, in a different method
ServletOutputStream out = response.getOutputStream();
...

out.clear()也帮助我摆脱了<%@page import=...之类的所有空行。

答案 2 :(得分:2)

确保消除view_image.jsp中的所有输出。简单的换行符可以负责生成输出。

例如,如果你有这些声明......

<%@ page import ... %>
<%@ page import ... %>

......你应该这样写它

<%@ page import ... %><%@ page import ... %><%
...%>

如果您查看已编译的servlet代码,则在图像响应之前不应该看到out.write("\r\n")

更好的方法是将view_image.jsp更改为Servlet,但如果不能这样做,删除jsp中的换行符就是一种解决方法。

答案 3 :(得分:1)

试试这个,虽然它不是最好的解决方案,但它确实有效。

in.close();
out2.flush();
out.clear();
out = pageContext.pushBody(); 

其中'in'是InputStream(如果您正在使用它),'out2'是新的response.getOutputStream(),'out'是默认的JspWriter

答案 4 :(得分:1)

    <%@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();}
    %>

答案 5 :(得分:0)

将view_image.jsp转换为映射到ViewImage的Servlet,并将其称为

<img src='<%= request.getContextPath() %>/ViewImage?pat_acc=<%=Pat_Acct%>' style='position: absolute; left: 0pt; top: 0px;' "/> 

在JSP文件中。

答案 6 :(得分:0)

尝试从jsp文件中删除所有模板文本。例如,

1 <%@
2    ....
3 %>
4 <%
5    ....
6 %>

第3行和第4行之间有一个'\ n',它被视为模板文本,调用response.getWriter()将'\ n'写入客户端。在第6行之后,也可能存在不可见的空格,这会使输出流搞砸。但是第5行可以提前return来避免这种情况。

答案 7 :(得分:0)

我刚刚在最近的工作中遇到了同样的问题。

我们有一个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();

它为我解决了这个问题。

答案 8 :(得分:0)

在Spring中,您可以解决此问题的更改

            response.getOutputStream().write(cabecera.getBytes());

            response.getWriter().write(cabecera);

答案 9 :(得分:0)

我有这个代码并修改如下:

@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,因为从这种方法来看,我期待下载。根据{{​​3}}给出的解释,我解决了我的问题。

答案 10 :(得分:0)

如果您在servlet中遇到此问题,那么在从servlet发送响应到浏览器时:

PrintWriter out=response.getWriter();

这应该是你可以在servlet中编写最终发送到浏览器的html代码的第一个语句