2009-12-01 7 views
48

Можно создать дубликат:
Should one call .close() on HttpServletResponse.getOutputStream()/.getWriter()?Должен ли я закрывать выходной поток сервлета?

Несу ли я ответственность за закрытие HttpServletResponse.getOutputStream() (или getWriter() или даже InputStream) или я должен оставить его на контейнер?

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException { 
    OutputStream o = response.getOutputStream(); 
    ... 
    o.close(); //yes/no ? 
} 

ответ

59

Вам действительно не нужно это делать.

Правило большого пальца: если вы не создали/не открыли его самостоятельно, используя new SomeOutputStream(), тогда вам не нужно его закрывать. Если это было, например, new FileOutputStream("c:/foo.txt"), то вам, очевидно, нужно закрыть его самостоятельно.

Причины, по которым некоторые люди по-прежнему делают это, равны , обеспечивают, что больше ничего не будет записано в тело ответа. Если это когда-либо произойдет, то это приведет к IllegalStateException в журналах приложений, но это не повлияет на клиента, поэтому клиент все равно получит правильный ответ. Это также более легкий отладчик, чтобы выявить потенциальные проблемы в цепочке запроса-ответа, которые вы не увидели бы на первый взгляд. Например, что-то еще добавляет больше данных в тело ответа где-то дальше в цепочке.

Другая причина, по которой вы видите среди стартеров, заключается в том, что они просто хотели предотвратить, что больше данных записывается в тело ответа. Вы часто это видите, когда JSP неправильно играет роль в ответе. Они просто игнорируют IllegalStateException s в журналах. Излишне говорить, что эта конкретная цель bad.

+1

Возможно, вы захотите закрыть поток, если вы открыли другой InputStream, чтобы его обернуть, поскольку в контейнере не будет видимости потока обтекания, который может содержать незафиксированные байты. В идеале вы просто очищаете() поток обертывания, если это что-то вроде BufferedOutputStream, но я обнаружил, что при использовании CipherOutputStream этот класс не полностью записывает данные (я считаю, что в этом случае не без оснований). В этой ситуации необходимо было вызвать close() для клиента, чтобы получить правильный ответ. –

8

Нет, вам не нужно его закрывать. Если вы делаете, вы в основном заканчиваете ответ клиенту. После закрытия потока вы не можете отправить что-либо еще клиенту до следующего запроса. Вы не открыли поток, поэтому вам не нужно закрывать его.

+14

Право. Как на ферме: оставьте ворота точно так же, как вы их нашли. – erickson

Смежные вопросы