2016-04-01 19 views
1

Mein RSS-Servlet verwendet Try-with-Ressource für die OutputStream out des HttpServletResponse und dem Schriftsteller dafür. In einigen Fällen SomeException während die Erzeugung des RSS-Dokument geworfen wird, wobei in diesem Fall muss ich einen HTTP-Status 500 an den Client zurück:versuchen-with-Ressource vs java.lang.IllegalStateException: Kann nicht sendError() aufrufen, nachdem die Antwort begangen wurde

try (ServletOutputStream out = response.getOutputStream(); 
    OutputStreamWriter writer = new OutputStreamWriter(out, "utf-8")) { 
     response.setContentType("text/xml"); 

     // Generate RSS here 

    } catch (SomeException e) { 
     response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); 
     return; 
    } 

jedoch durch die Zeit response.sendError() genannt wird, hat $ die $ aus bereits geschlossen und ich sage IllegalStateException sagen, dass die Antwort bereits festgeschrieben wurde (Schließen des Streams scheint die Antwort automatisch zu committen).

Wenn ich die Initialisierung von out und writer außerhalb des try-Blocks verschiebe und sie in einem finally-Block schließe (die vor-Java7-Methode), wird der Fehlercode korrekt gesendet.

Ich habe mich gefragt, ob es eine Möglichkeit gibt, try-with-resource weiter zu verwenden und trotzdem Fehlercodes im Falle einer Ausnahme zurückgeben zu können.

Danke!

+1

können Sie einen _outer_ try-with-resources und einen _inner_ try-catch verwenden ... – jtahlborn

Antwort

1

Sie müssen Ressourcen, die Sie nicht selbst erstellt haben, nicht schließen. Der Container hat die zugrundeliegende OutputStream von sich aus erstellt und ist somit auch selbst für die ordnungsgemäße Schließung verantwortlich. Sie sollten sich darüber im Klaren sein, dass der Container bereits eine Try-with-Resources um die Servlet-Methode doXxx() platziert hat. Siehe auch Should I close the servlet outputstream?

Anders ausgedrückt, ist die gesamte Try-mit-Ressourcen auf OutputStream innerhalb doXxx() nicht erforderlich.

Just do:

try { 
    // Generate RSS here 

    OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), "UTF-8")) { 
    response.setContentType("text/xml"); 

    // Write RSS here. 

} catch (SomeException e) { 
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); 
} 

Unrelated auf das konkrete Problem, wenn Sie erneut auslösen jede geprüfte Ausnahme als ServletException, dann wird der Behälter auch ganz von selbst kümmert sich um den richtigen Antwort-Code und Botschaft.

try { 
    // ... 
} catch (SomeException e) { 
    throw new ServletException(e); 
}