2009-11-27 10 views
16

Ich habe einigen Produktionscode bekommt, die etwas tut, wie:Ist es notwendig, den von HttpServletRequest zurückgegebenen Eingabestream zu schließen?

HttpServletRequest httpServletRequest 
... 
DataInputStream dis = new DataInputStream(httpServletRequest.getInputStream()) 

Diese Ströme werden nie explizit geschlossen. Ich gehe hier davon aus, dass der Servlet-Container das verwaltet (JBoss Web). Was ist der richtige Weg, damit umzugehen?

+0

Danke für das Feedback Jungs. Ich habe diese Frage ursprünglich gestellt, weil ich auf ein Problem mit JBoss Web 2.1.2 (in JBoss 5.0.1) stieß. Der ChunkedInputFilter kann bei der Verarbeitung von Chunked-Transfer-Encoding für immer eine Schleife durchlaufen. Ich dachte, es wäre mein Code. In JBoss Web 2.1.3 gibt es dafür eine Lösung. – Conor

Antwort

25

Die Daumenregel in I/O ist, wenn Sie nicht die Eingangsstromquelle selbst geöffnet/erstellen, dann müssen Sie es nicht unbedingt auch schließen. Hier wickeln Sie nur den Eingangsstrom der Anfrage um, sodass Sie ihn nicht unbedingt schließen müssen.

Wenn Sie die Eingabe selbst geöffnet haben, z. new FileInputStream("c:/file.ext") dann musst du es natürlich im finally block selbst schließen. Der Behälter sollte dies unter der Haube tun.

+0

Wenn die von Ihnen aufgerufene Methode mit 'open' wie' openStream' von java.net.URL startet, bedeutet das, dass Sie sie selbst geöffnet haben und sie auch schließen müssen? –

+1

Ich schätze eine Ausnahme ist, wenn der neue Stream, den Sie geöffnet haben, nur ein Wrapper ist: 'new BufferedInputStream (inputStream)' dann müssen Sie ihn möglicherweise nicht schließen, weil er von jedem geschlossen werden sollte, der 'inputStream' öffnet? – gerrytan

+0

Ich denke, wir haben eine Ausnahme mit 'URLConnection getInputStream()' und 'getOutputStream()' wie die Orakeldokumentation [(Oracle Doc)] (http://docs.oracle.com/javase/tutorial/networking/urls/) readingWriting.html) scheint der Stream implizit geöffnet zu sein. Auch dieser [stackoverflow post] (http://stackoverflow.com/questions/4844535/why-do-you-have-to-call-urlconnectiongeputstream-to-be-able-to-write-out-to) beschreibt, dass Sie Ich muss den Stream schließen, selbst wenn du gerade 'get ... Stream()' aufgerufen hast. – tObi

3

Der Container wird damit umgehen. Es ist immer ein guter Codierungsstil, Ressourcen an der Stelle zu schließen, an der Sie sie zugewiesen haben. (Ich war falsch in meinem ursprünglichen Beitrag. Ich dachte, Sie öffneten den Strom. Sollte mehr sorgfältig lesen.)

8

Sie sollten unbedingt nicht schließen Sie diese Ströme selbst, das ist die Aufgabe des Containers. Wenn Sie dies manuell tun, besteht die Gefahr, dass der Anforderungslebenszyklus beeinträchtigt wird, und einige Container können Ihnen dabei heftig widersprechen.

0

Die Spezifikation (bis zu dem 3.0-Kandidaten) sagt nicht (soweit ich das beurteilen kann). In Ermangelung kanonischer Informationen könnten Sie der Implementierung ausgeliefert sein.

Der Quellcode für die Referenzimplementierung auf der Sun Servlet page erwähnt:

Die Implementierung Referenz wird in der Java EE 5 SDK und auch in der Open-Source-Java-Plattform, Enterprise Edition (Java EE) enthalten Anwendungsserver, verfügbar über das GlassFish-Projekt, auf java.net. Der Quellcode der Referenzimplementierung für die Servlet-Technologie ist im svn-Repository auf java.net verfügbar. Zusätzliche Informationen zu allen Webtier-Technologien in GlassFish finden Sie auf der GlassFish Webtier-Seite.

Überprüfen Sie das Verhalten möglicherweise so nahe an einer endgültigen Antwort, wie Sie erhalten werden.

Verwandte Themen