Dans les servlets Java, on peut accéder au corps de la réponse via response.getOutputStream()
ou response.getWriter()
. Doit-on appeler .close()
cela OutputStream
après avoir été écrit?
D'une part, il y a l'exhortation blochienne de toujours fermer l' OutputStream
art. D'un autre côté, je ne pense pas que dans ce cas, il y a une ressource sous-jacente qui doit être fermée. L'ouverture / la fermeture des sockets est gérée au niveau HTTP, pour permettre des choses comme les connexions persistantes et autres.
java
servlets
outputstream
Steven Huwig
la source
la source
close()
qui ne fait rien. Ce que vous devez faire est de fermer toutes les ressources fermables.Réponses:
Normalement, vous ne devez pas fermer le flux. Le conteneur de servlet fermera automatiquement le flux une fois le servlet exécuté dans le cadre du cycle de vie de la demande de servlet.
Par exemple, si vous fermiez le flux, il ne serait pas disponible si vous implémentiez un filtre .
Cela dit, si vous le fermez, rien de grave ne se passera tant que vous n'essayez pas de l'utiliser à nouveau.
EDIT: un autre lien de filtre
EDIT2: adrian.tarau est correct en ce sens que si vous voulez modifier la réponse après que le servlet a fait son travail, vous devez créer un wrapper étendant HttpServletResponseWrapper et tamponner la sortie. C'est pour empêcher la sortie d'aller directement au client mais vous permet également de vous protéger si le servlet ferme le flux, comme dans cet extrait (c'est moi qui souligne):
Article
On peut déduire de cet article officiel de Sun que la fermeture
OutputStream
d'un servlet est quelque chose qui est une occurrence normale, mais n'est pas obligatoire.la source
La règle générale d'entre eux est la suivante: si vous avez ouvert le flux, vous devez le fermer. Sinon, vous ne devriez pas. Assurez-vous que le code est symétrique.
Dans le cas de
HttpServletResponse
, c'est un peu moins clair, car il n'est pas évident si l'appelgetOutputStream()
est une opération qui ouvre le flux. Le Javadoc dit simplement que "Returns a ServletOutputStream
"; de même pourgetWriter()
. Dans tous les cas, ce qui est clair, c'est queHttpServletResponse
"possède" le flux / l'écrivain, et qu'il (ou le conteneur) est responsable de le refermer.Donc, pour répondre à votre question - non, vous ne devez pas fermer le flux dans ce cas. Le conteneur doit le faire, et si vous y entrez avant, vous risquez d'introduire de subtils bogues dans votre application.
la source
close()
quand j'ai terminé avec le flux, le client revient immédiatement et le reste du servlet continue de s'exécuter. Cela ne rend-il pas la réponse un peu plus relative? par opposition à un oui ou un non définitifS'il y a une chance que le filtre soit appelé sur une ressource «incluse», vous ne devriez certainement pas fermer le flux. Cela entraînera l'échec de la ressource d'inclusion avec une exception «flux fermé».
la source
Vous devez fermer le flux, le code est plus propre puisque vous appelez getOutputStream () et le flux ne vous est pas passé en tant que paramètre, alors que vous l'utilisez généralement et n'essayez pas de le fermer. L'API Servlet n'indique pas que si le flux de sortie peut être fermé ou ne doit pas être fermé, dans ce cas, vous pouvez fermer le flux en toute sécurité, tout conteneur là-bas s'occupe de fermer le flux s'il n'a pas été fermé par le servlet.
Voici la méthode close () dans Jetty, ils ferment le flux s'il n'est pas fermé.
De même, en tant que développeur d'un filtre, vous ne devez pas présumer que OutputStream n'est pas fermé, vous devez toujours transmettre un autre OutputStream si vous souhaitez modifier le contenu une fois que le servlet a fait son travail.
EDIT: Je ferme toujours le flux et je n'ai eu aucun problème avec Tomcat / Jetty. Je ne pense pas que vous devriez avoir des problèmes avec un conteneur, ancien ou nouveau.
la source
Un autre argument contre la fermeture du
OutputStream
. Regardez ce servlet. Cela lève une exception. L'exception est mappée dans le fichier web.xml à une erreur JSP:Le fichier web.xml contient:
Et l'erreur.jsp:
Lorsque vous chargez
/Erroneous
dans le navigateur, vous voyez la page d'erreur affichant "Une erreur". Mais si vous annulez le commentaire de laout.close()
ligne dans le servlet ci-dessus, redéployez l'application et rechargez,/Erroneous
vous ne verrez rien dans le navigateur. Je n'ai aucune idée de ce qui se passe réellement, mais je suppose que celaout.close()
empêche la gestion des erreurs.Testé avec Tomcat 7.0.50, Java EE 6 avec Netbeans 7.4.
la source