java.lang.IllegalStateException: STREAM when writing excel file as response with Jetty and struts

11,271

The exception ...

Caused by: java.lang.IllegalStateException: STREAM
    at org.eclipse.jetty.server.Response.getWriter(Response.java:944)
    ...

... means that your code attempted to access HttpServletResponse.getWriter() after having already accessed HttpServletResponse.getOutputStream()

At the point in time when the .getWriter() call occurred, the state of the response was already in STREAM mode, hence the IllegalStateException

Thats not allowed per the servlet spec.

Share:
11,271

Related videos on Youtube

Avi
Author by

Avi

Updated on July 08, 2022

Comments

  • Avi
    Avi almost 2 years

    I have a code that creates an excel file using struts and jetty.

    In the struts.xml file I declared:

    <action name="full-export-excel" method="exportFullDataSetToExcel"
            class="com.me.ExcelAction">
      <result name="success" type="stream">
        <param name="contentType">application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8
        </param>
        <param name="inputName">input</param>
        <param name="contentLength">${contentLength}</param>
        <param name="bufferSize">1024</param>
        <param name="contentDisposition">filename="${fileName}"</param>
      </result>
    </action>
    

    In my java code:

    final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    XSSFWorkbook excelWorkBook = excelBuilder.createExcelWorkBook(reportObjects, columnMapper); // My code for creating excel file
    excelWorkBook.write(outputStream);
    input = new ByteArrayInputStream(outputStream.toByteArray());
    

    I also have a getter for the content length:

    public Integer getContentLength() throws IOException {
      return input.available();
    }
    

    This whole code runs under jetty. And when trying to download a large file I get this exception:

    Caused by: java.lang.IllegalStateException: STREAM
        at org.eclipse.jetty.server.Response.getWriter(Response.java:944)
        at org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper.getWriter(CompressedResponseWrapper.java:440)
        at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:152)
    

    EDIT: It works for smaller excel files but not for large ones. I also tried to write the large files to the file-system (to make sure that's not the excel exporting but rather a communication issue) and it worked.

    • Avi
      Avi almost 10 years
      @AndreaLigios = Yep :D Just out of curiosity, why did you suggest it? Did you have any assumption?
  • Avi
    Avi almost 10 years
    Hmm... But what could cause it? The same code works for smaller files but not for large files. Do you have any idea why?
  • Avi
    Avi almost 10 years
    Happens only in production :/ I couldn't reproduce it on dev machine. Not even when I created a very large file....
  • Avi
    Avi almost 10 years
    That was in case not the issue for me. This was caused due to an exception raised and tried to do getOutputStream() and this obfuscated my real problem. I accepted the answer because I think it will benefit others who'll come to this question, even thought it wasn't my original problem :) Thanks!
  • Andrea Ligios
    Andrea Ligios almost 10 years
    @Avi can you tell us which the problem was (by answering your own question, or just in comment) ?
  • Avi
    Avi almost 10 years
    @AndreaLigios My problem was that the client had timeout on the request and it cancelled the request. On the server side there was an exception handler the called getWriter() and changed the response after the getOutputStream() was already called (exactly as described in this answer). The log gave this exception but the root cause was the cancellation of the request by the client side. It was obfuscated by the IllegalStateException due to the way we handled the exception. Given my question, Joakim's answer is a full answer to how I asked the question. So I accepted it.
  • Andrea Ligios
    Andrea Ligios almost 10 years
    Ah timeout, right... you just needed to return an error of type stream instead of dispatcher then :) Thanks for clearing the curiosity