ama
ama

Reputation: 311

java.lang.IllegalStateException: getOutputStream() has already been called for this response

I get the following exception when I'm trying to request loading images from server on client side:

241132533 [TP-Processor1] ERROR [/jspapps].[jsp] - Servlet.service() for servlet jsp threw exception java.lang.IllegalStateException: getOutputStream() has already been called for this response

Can any one explain this exception to me and also how to get over it?

Upvotes: 9

Views: 76511

Answers (11)

Manish
Manish

Reputation: 11

if you are facing this problem in servlets then while sending the response to the browser from servlet:

PrintWriter out=response.getWriter();

This should be the first statement aftter that you can write your html code in servlet that is eventually send to the browser

Upvotes: 0

3AK
3AK

Reputation: 1361

I had this code and fixed it like this:

@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;
}

I returned null because, from this method, I was expecting a download. As per the explanation given here, I fixed my problem.

Upvotes: 0

In Spring, you can solve this issue changing

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

to

            response.getWriter().write(cabecera);

Upvotes: 0

Yan Yan
Yan Yan

Reputation: 65

I just encountered the same problem in my recent work.

We have a servlet filter in which we use ServletResponse.getWriter() method to write the body, and in some Spring MVC controller, we also use response.getOutputStream() to write something like images(array of bytes) into body.

Since every request will go through filter, and based on Java API doc:

"Either this method(getWriter()) or getOutputStream() may be called to write the body, not both."

That's the reason why we got the "java.lang.IllegalStateException: getOutputStream() has already been called for this response" exception.

So in that filter, I changed the code to:

ServletOutputStream sos = response.getOutputStream();
sos.write(newHtml.getBytes("UTF8")); // newHtml is a String.
sos.flush();

It fixed this issue for me.

Upvotes: 0

Surendra
Surendra

Reputation: 29

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

Upvotes: 1

Josef Hammer
Josef Hammer

Reputation: 97

I just stumbled upon this old question as I had the same issue. In the end it was quite easy to get rid of the exception: Just call out.clear() before:

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

out.clear() also helped me to get rid of all those empty lines from <%@page import=... and the like.

Upvotes: 8

Harke
Harke

Reputation: 1289

Try this, it is not the best of solutions though, but it works.

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

Where 'in' is the InputStream (if you are using it), 'out2' is the new response.getOutputStream() and 'out' is the default JspWriter.

Upvotes: 1

Soundlink
Soundlink

Reputation: 3931

Make sure eliminating all output in your view_image.jsp. Simple line breaks can be responsible for generating output.

For example, if you have these declarions...

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

... you should write them this way

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

If you take a look to the compiled servlet code you shouldn't see out.write("\r\n") before your image response.

A better way would be to change your view_image.jsp into a Servlet, but if you can't do that, removing the line breaks in the jsp is a workaround.

Upvotes: 2

irreputable
irreputable

Reputation: 45433

try remove all template texts from jsp file. for example,

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

there is a '\n' between line 3 and 4, and it is treated as template text, response.getWriter() is called to write that '\n' to client. after line 6, there could be invisible whitespaces too which will screwup the outputstream. but line 5 can return early to avoid that.

Upvotes: 0

Behrang Saeedzadeh
Behrang Saeedzadeh

Reputation: 47913

Turn view_image.jsp into a Servlet mapped to ViewImage and call it like

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

in your JSP file.

Upvotes: 0

BalusC
BalusC

Reputation: 1108537

can any one explain this exception to me

You're attempting to write binary data to response.getOutputStream() using raw Java code inside a JSP file which itself is already using response.getWriter() to write any template text. See also the Throws part of the linked javadocs.

and also how to get over it?

Write Java code in a real Java class instead. Create a class which extends HttpServlet, move all that Java code to there, map it in web.xml and change the request URL to call the servlet instead.

See also:

Upvotes: 7

Related Questions