2016-02-26 5 views
0

Я получаю следующее сообщение об ошибке в моей странице AttachedFiles.jsp:Должен ли я заливать ServletOutputStream каждый раз, когда я пишу на него?

SEVERE: Servlet.service() for servlet [jsp] in context with path [/da8] threw exception [java.lang.IllegalStateException: getOutputStream() has already been called for this response] with root cause 
java.lang.IllegalStateException: getOutputStream() has already been called for this response 
    at org.apache.catalina.connector.Response.getWriter(Response.java:678) 
    at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213) 
    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125) 
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118) 
    at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:194) 
    at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:126) 
    at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80) 
    at org.apache.jsp.jsp.AttachedFiles_jsp._jspService(AttachedFiles_jsp.java:786) 
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) 
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432) 
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395) 

Моя предыдущая версия была:

fileIn.close(); 
outStream.flush(); 
outStream.close(); 

сразу после время цикла, но я думал, что это хорошая практика, чтобы поместить закрытие все объекты в блоке finally. Я также читал, что close() также очищает OutputStream.

После того как я сделал это изменение я получаю выше ошибки:/

AttachedFiles.jsp

FileInputStream fileIn = null; 
    ServletOutputStream outStream = null; 
    try 
    { 
     File fileToDownload = new File(file); 

     response.setContentType("APPLICATION/OCTET-STREAM"); 
     String fileName = request.getParameter("fileName"); 
     if(fileName == null) fileName = ""; 

     String disHeader = "Attachment; Filename=\""+fileName+"\""; 
     response.setHeader("Content-Disposition", disHeader); 
     fileIn = new FileInputStream(fileToDownload); 
     outStream = response.getOutputStream(); 

     byte[] outputByte = new byte[(int) fileToDownload.length()]; 

     //copy binary contect to output stream 
     while(fileIn.read(outputByte) != -1) 
     { 
      outStream.write(outputByte); 
     } 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    finally 
    { 
     try 
     { 
      outStream.close(); 
      if (fileIn != null) 
       fileIn.close(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    } 

Кто-нибудь знает, почему я получаю эту ошибку?

если это так, должен ли я скрывать внутри цикла, сразу после записи в outputStream?

+0

Я бы сказал, что, поскольку вы не открыли поток, который он не твой, чтобы закрыть. Это, возможно, более верно, учитывая, что вы включили все это в JSP - сомнительная практика сама по себе. Флеш не нужен вообще - после того, как управление покинет JSP, сценарий/поток будет очищен. Единственный раз, когда я использовал флеш, - это частичные обновления во время обработки. – stdunbar

+1

Никогда не зачищайте внутри петли. В цикле копирования игнорируется значение, возвращаемое 'read(), которое должно быть представлено в качестве третьего параметра' write() ', а также параметр смещения нуля. – EJP

ответ

0

JSP компилируется в сервлет. Он уже готовит это неявные объекты в результате Servlet:

  • запрос
  • ответ
  • из (PrintWriter)
  • сессия
  • приложение
  • конфигурации
  • PageContext
  • страница

Вы можете использовать для написания. Но из него - Писатель, и так он пишет персонажей. Возможно, вы захотите записать двоичные файлы.

Было бы здорово, если бы вы переписали код в Servlet. Это было бы чище.

В противном случае, чтобы решить внутри JSP, все, что можно сказать здесь, было бы взломом ... Не будет круто.

  • Вы можете вставить явный «возврат»; после написания.
  • Вы можете попробовать очистить буферы и сбросить внутреннее состояние.
  • Добавить сумасшедшие уловы Arround ваш
  • JSP
  • Al мере, не слишком Hacky, добавить <% @ страница trimDirectiveWhitespaces = «истинный»%>, чтобы гарантировать JspWriter не будет создан для этой страницы.