Em Java Servlets, pode-se acessar o corpo da resposta via response.getOutputStream()
ou response.getWriter()
. Deve-se invocar .close()
isso OutputStream
depois de ter sido escrito?
Por um lado, existe a exortação blochiana de sempre fechar OutputStream
s. Por outro lado, não acho que neste caso haja um recurso subjacente que precise ser fechado. A abertura / fechamento de sockets é gerenciado no nível HTTP, para permitir coisas como conexões persistentes e tal.
java
servlets
outputstream
Steven Huwig
fonte
fonte
close()
que não faz nada. O que você deve fazer é fechar todos os recursos que podem ser fechados.Respostas:
Normalmente você não deve fechar o fluxo. O contêiner de servlet fechará automaticamente o fluxo após a conclusão da execução do servlet como parte do ciclo de vida da solicitação do servlet.
Por exemplo, se você fechasse o fluxo, ele não estaria disponível se você implementasse um Filtro .
Dito isso, se você o fechar, nada de ruim acontecerá, desde que você não tente usá-lo novamente.
EDIT: outro link de filtro
EDIT2: adrian.tarau está correto em que se você quiser alterar a resposta após o servlet ter feito seu trabalho, você deve criar um wrapper estendendo HttpServletResponseWrapper e bufferizar a saída. Isso evita que a saída vá diretamente para o cliente, mas também permite que você proteja se o servlet fecha o fluxo, conforme este trecho (grifo meu):
Artigo
Pode-se inferir desse artigo oficial da Sun que o fechamento
OutputStream
de um servlet é algo normal, mas não obrigatório.fonte
A regra geral deles é esta: se você abriu o fluxo, deve fechá-lo. Do contrário, não deveria. Certifique-se de que o código seja simétrico.
No caso de
HttpServletResponse
, é um pouco menos claro, já que não é óbvio se a chamadagetOutputStream()
é uma operação que abre o fluxo. O Javadoc apenas diz que "Returns a ServletOutputStream
"; da mesma forma paragetWriter()
. De qualquer forma, o que está claro é queHttpServletResponse
"possui" o stream / gravador, e ele (ou o contêiner) é responsável por fechá-lo novamente.Portanto, para responder à sua pergunta - não, você não deve fechar o fluxo neste caso. O contêiner deve fazer isso e, se você entrar lá antes, corre o risco de introduzir bugs sutis em seu aplicativo.
fonte
close()
quando termino o stream, o cliente retorna imediatamente e o resto do servlet continua em execução. Isso não torna a resposta um pouco mais relativa? em oposição a um sim ou não definitivoSe houver alguma chance de o filtro ser chamado em um recurso 'incluído', você definitivamente não deve fechar o fluxo. Isso fará com que o recurso de inclusão falhe com uma exceção 'fluxo fechado'.
fonte
Você deve fechar o fluxo, o código é mais limpo, pois você invoca getOutputStream () e o fluxo não é passado para você como um parâmetro, quando normalmente você apenas o usa e não tenta fechá-lo. A API do Servlet não afirma que se o fluxo de saída pode ser fechado ou não deve ser fechado, neste caso você pode fechar o fluxo com segurança, qualquer contêiner lá fora cuida de fechar o fluxo se ele não foi fechado pelo servlet.
Aqui está o método close () no Jetty, eles fecham o fluxo se não for fechado.
Além disso, como desenvolvedor de um Filtro, você não deve presumir que o OutputStream não está fechado, você sempre deve passar outro OutputStream se quiser alterar o conteúdo após o servlet ter feito seu trabalho.
EDIT: Estou sempre fechando o stream e não tive problemas com o Tomcat / Jetty. Não acho que você deva ter problemas com qualquer container, antigo ou novo.
fonte
Outro argumento contra o fechamento do
OutputStream
. Olhe para este servlet. Ele lança uma exceção. A exceção é mapeada no web.xml para um erro JSP:O arquivo web.xml contém:
E o error.jsp:
Ao carregar
/Erroneous
no navegador, você vê a página de erro exibindo "Um erro". Mas se você remover o comentário daout.close()
linha no servlet acima, reimplantar o aplicativo e recarregar,/Erroneous
você não verá nada no navegador. Não tenho ideia do que realmente está acontecendo, mas acho que issoout.close()
impede o tratamento de erros.Testado com Tomcat 7.0.50, Java EE 6 usando Netbeans 7.4.
fonte