Announcement

Collapse
No announcement yet.

IllegalStateException nach erfolgreichem Download (struts2)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • IllegalStateException nach erfolgreichem Download (struts2)

    Hallo zusammen,

    ich arbeite an einer struts2-Anwendung. Das Ziel ist es, auf einer Webseite mehrere Download-Links anzubieten, über die Dateien aus einem zentralen Verzeichnis heruntergeladen werden können.
    Soweit funktioniert die Anwendung auch inzwischen sehr gut. Allerdings tritt jedesmal, wenn einer der Downloadlinks angewählt wird, folgender Fehler auf:

    Code:
    SCHWERWIEGEND: Servlet.service() for servlet [default] in context with path [/projektverzeichnis] threw exception
    java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
    	at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:451)
    	at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:760)
    	at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:513)
    	at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:422)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    	at java.lang.Thread.run(Thread.java:662)
    Der Download an sich funktioniert reibungslos. Die Anwendung gibt sich nach außen hin auch fehlerfrei, d.h. ein Nutzer bekommt davon nichts mit. Trotz diversen Suchens und Ausprobierens, bin ich der Fehlerursache aber nicht wirklich näher gekommen. Erste Hinweise gingen in Richtung des Tomcat. Allerdings habe ich dort keinen Ansatz finden können. Wenn ich mit dem Eclipse-Debugger durchgehe, werden alle meine Codeteile fehlerfrei durchlaufen. Deshalb vermute ich, dass der Fehler irgendwo tief im System geworfen wird.

    Kennt jemand diesen Fehler oder hat eventuell eine Idee, wo ich noch schauen könnte?

    Vielen Dank schoneinmal!
    MichaelPF

  • #2
    Es wird versucht den Response, der schon mit einer Ausgabe belegt ist (wahrscheinlich mit dem Download) mit einer weiteren Ausgabe zu belegen. Das ist nicht möglich. Sofern der Response einmal mit einem Content belegt ist kann nicht ein zweiter nachgeschoben oder der erste verändert werden.
    Wird also bsp. im Response eine PDF-Datei geschrieben, kann nicht noch eine HTML-Seite hintergeschoben werden
    Christian

    Comment


    • #3
      Danke für die schnelle Antwort.

      Wie kann ich denn verhindern, daß er genau das tut? Ich sehe nicht, wo der Response ein zweites Mal mit einer Ausgabe belegt wird. Ich könnte mir vorstellen, daß es die JSP-Seite ist, die neu geladen wird. Kann das Belegen mit einer weiteren Ausgabe irgendwie verhindert werden?

      Die execute-Methode der Download-Action sieht folgendermaßen aus:

      Code:
      public String execute() {
      	// Keine Zugriffe mit '\' oder '/' zulassen, damit das Verzeichnis
      	// nicht gewechselt werden kann.
      	if (this.fileName.contains("\\") || this.fileName.contains("/")) {
      		return ERROR;
      	}
      
      	HttpServletResponse response = getServletResponse();
      	File sourceFile = new File(this.getConfig().getStoragePathExportFiles(), this.fileName);
      		
      	response.setContentType("text/csv");
      	response.setHeader("Content-Disposition", "attachment;filename=" + this.fileName);
      	response.setDateHeader("Last-Modified", sourceFile.lastModified());
      	response.setBufferSize(1024);
      		
      
      	// Gebe Inhalt der Datei an den Browser aus
      	try {
      		ServletOutputStream out = response.getOutputStream();
      		FileCopyHelper.copyToStream(sourceFile, out);
      		out.flush();
      		out.close();
      	} catch (IOException ioe) {
      		return ERROR;
      	}
      		
      	
      	return SUCCESS;
      }
      In der struts.xml habe ich folgende Angaben gemacht:
      Code:
      <action name="Download" class="Download">
      	<result name="error">/pages/Download.jsp</result>
      	<result>/pages/Download.jsp</result>
      </action>

      Comment


      • #4
        In jedem Fall ist die Rückgabe von ERROR oder SUCCESS falsch, da die ja wohl zu entsprechenden Seiten führen. Die können nicht mehr ausgegeben werden. Versuch null zurückzugeben. Des Weiteren könnte ein Fehler aufgetreten sein, da ja der Error aufgerufen werden soll. Weiterhin würde sich der Einsatz eines Logger empfehlen, in dem man die Fehler reinschreibt....
        Christian

        Comment


        • #5
          Guten Morgen!

          vielen Dank!
          Das war genau der Knackpunkt gewesen. Ich danke vielmals!

          Comment

          Working...
          X