4

When user clicks a certain link ,Using web services transfer document from A Remote ECM system to user machine.

So I have created servlet and from Query string and get parameters from URL .

Depending on parameters attributes several web services related methods were invoked to get file details and file content. now invoke file transfer between servlet and user system.

Biggest concern is that with the below exceptions , code fragment works fine. user can able to save document in desired location. I was trying to figure out why I am getting this error.

Errors:

java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:611)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
t  DownloadServlet.doGet(DownloadServlet.java:99)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)

Code## DownloadServlet.java

 getDocument(HttpServletRequest request,HttpServletResponse response)
   {
 \\used Custom web services methods to get filename with extensions from external ECM system 
   File resultFile = content.getAsFile();
   response.setContentType("application/octet-stream");  
   ServletOutputStream outStream = response.getOutputStream();          
   try {
       response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
       byte[] byteBuffer = new byte[BUFSIZE];
       DataInputStream in = new DataInputStream(new FileInputStream(file));
          while ((in != null) && ((length = in.read(byteBuffer)) != -1)){
            outStream.write(byteBuffer,0,length);
            }
            in.close();
            outStream.flush();                              
      } catch (Exception e) {
          e.printStackTrace();
      }finally{
          outStream.close();
      }

 }
Killer
  • 592
  • 1
  • 6
  • 24
rakesh choudhury
  • 53
  • 1
  • 1
  • 7
  • Hope you have visited these links: http://stackoverflow.com/questions/14065561/java-lang-illegalstateexception-getoutputstream-has-already-been-called-for-t http://stackoverflow.com/questions/14951041/getting-exception-java-lang-illegalstateexception-getoutputstream-has-already – Pramod Karandikar Sep 18 '14 at 10:04
  • Please format your code properly. The way you posted it makes it really hard to follow. – Keppil Sep 18 '14 at 10:05
  • It's already answer in many place. Like http://stackoverflow.com/questions/1776142/getoutputstream-has-already-been-called-for-this-response – Janny Sep 18 '14 at 10:07
  • @Jani i have seen that post . In this case i am using only servlet. – rakesh choudhury Sep 18 '14 at 10:17
  • As per log (DownloadServlet.java:99) giving Exception, Can you identify the particulate line in your post? – Janny Sep 18 '14 at 10:22
  • Line 99 is getDocument() method which is inside doget(HttpServletRequest request, HttpServletResponse response) – rakesh choudhury Sep 18 '14 at 10:25
  • If you use interceptor which works with it at the same time, please check it. Maybe interceptor use response - outputStream. – egemen Jun 21 '17 at 08:48

2 Answers2

10

I had same problem while working with a web application using Struts 2 frame work. I searched for a while, and the solution that I found worked for me. I found somewhere that:

Basic rule of HTTP: one request, one response. You can only send back one thing to a request. Either an HTML page, or a PDF document, or an image etc. Java complains if you have already obtained a writer/outputstream as you should only be getting ONE of these.

In my case, the action class which downloads the file was returning back a String "sucess" to the request after the file download, and that caused the problem. I changed the return type of the method to void and issue resolved.

Joe
  • 101
  • 4
  • Thanks Joe. My action class isn't returning any thing it is Private void getDocument(....). if the transaction is unsuccessful and I was unable to get document ,I am setting response Conenttype as "text/html" and printing rest of the errors in HTMl page using PrintWriter – rakesh choudhury Sep 19 '14 at 08:29
2

You have issue with response.
So use this two line.

 response.getOutputStream().flush();
 response.getOutputStream().close();
Janny
  • 681
  • 1
  • 8
  • 33