Нужно назвать .close () на HttpServletResponse.getOutputStream ()/.getWriter ()?

Можно сделать несколько вещей диагностировать эту проблему. Во-первых, используйте поиск файла Windows для поиска жесткого диска блок (.dll). Как только у Вас есть список результатов, действительно Просмотрите->, Выбирают Details... и затем проверяют "Версию файла". Это отобразит номер версии в списке результатов, таким образом, Вы будете видеть, куда старая версия могла бы прибывать из.

кроме того, как Lars сказал, проверьте свой GAC для наблюдения, какая версия перечислена там. в статье This Microsoft говорится, что блоки, найденные в GAC, не копируются локально во время сборки, таким образом, Вы, возможно, должны были бы удалить старую версию прежде, чем сделать восстанавливание всех. (См. мой ответ на этот вопрос для примечаний по созданию пакетного файла, чтобы сделать это для Вас)

, Если Вы все еще не можете выяснить, куда старая версия прибывает из, можно использовать приложение fuslogvw.exe, которое поставлется с Visual Studio для получения большей информации об обязательных отказах. Microsoft имеет информацию об этом инструменте здесь . Обратите внимание, что необходимо будет позволить регистрироваться путем установки HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion\EnableLog ключ реестра к 1.

90
задан Steven Huwig 21 July 2009 в 13:27
поделиться

3 ответа

Обычно вы не должны закрывать поток. Контейнер сервлета автоматически закроет поток после завершения работы сервлета в рамках жизненного цикла запроса сервлета.

Например, если вы закроете поток, он будет недоступен, если вы реализовали Фильтр .

Сказав все это, если вы его закроете, ничего плохого не произойдет, пока вы не не пытайтесь использовать его снова.

EDIT: еще одна ссылка на фильтр

EDIT2: adrian. tarau прав в том, что если вы хотите изменить ответ после того, как сервлет выполнил свою задачу, вы должны создать оболочку, расширяющую HttpServletResponseWrapper, и буферизовать вывод. Это сделано для предотвращения передачи вывода напрямую клиенту, но также позволяет вам защитить, если сервлет закрывает поток, в соответствии с этим отрывком (выделено мной):

Фильтр, который изменяет ответ, должен обычно фиксируют ответ перед ним возвращается клиенту. Путь к сделать это - передать сервлет, который генерирует ответ заменой поток. Резервный поток предотвращает сервлет от закрытия оригинала поток ответов, когда он завершится и позволяет фильтру изменять ответ сервлета.

Статья

Из той официальной статьи Sun можно сделать вывод, что закрытие выходного потока сервлета - это нормальное явление, но не обязательное.

88
ответ дан 24 November 2019 в 07:03
поделиться

Их общее правило таково: если вы открыли поток, то вы должны его закрыть. Если нет, то и не надо. Убедитесь, что код симметричен.

В случае HttpServletResponse он немного менее четкий, поскольку не очевидно, является ли вызов getOutputStream () операцией, которая открывает поток. Javadoc просто говорит, что « возвращает ServletOutputStream »; аналогично для getWriter () . В любом случае ясно, что HttpServletResponse «владеет» потоком / писателем, и он (или контейнер) отвечает за его повторное закрытие.

Итак, чтобы ответить на ваш вопрос - нет, вам следует не закрывайте поток в этом случае. Контейнер должен это сделать, и если вы попадете туда раньше,

70
ответ дан 24 November 2019 в 07:03
поделиться

Вы должны закрыть поток, код чище, поскольку вы вызываете getOutputStream (), и поток не передается вам в качестве параметра, когда обычно вы просто используете его и не пытаетесь закрыть. API сервлета не утверждает, что если выходной поток может быть закрыт или не должен быть закрыт, в этом случае вы можете безопасно закрыть поток, любой контейнер позаботится о закрытии потока, если он не был закрыт сервлетом.

Вот метод close () в Jetty, они закрывают поток, если он не закрыт .

public void close() throws IOException
    {
        if (_closed)
            return;

        if (!isIncluding() && !_generator.isCommitted())
            commitResponse(HttpGenerator.LAST);
        else
            flushResponse();

        super.close();
    }

Также как разработчик Фильтра вы не должны предполагать, что OutputStream не закрыт, вы всегда должны передавать другой OutputStream, если хотите изменить содержимое после того, как сервлет выполнил свою работу.

EDIT: I ' m всегда закрывает поток, и у меня не было проблем с Tomcat / Jetty. Я не думаю, что у вас должны возникнуть проблемы с каким-либо контейнером, старым или новым.

public void close() throws IOException
    {
        if (_closed)
            return;

        if (!isIncluding() && !_generator.isCommitted())
            commitResponse(HttpGenerator.LAST);
        else
            flushResponse();

        super.close();
    }

Также как разработчик фильтра вы не должны предполагать, что OutputStream не закрыт, вы всегда должны передавать другой OutputStream, если хотите изменить содержимое после того, как сервлет выполнил свою работу.

EDIT: Я всегда закрывал поток, и у меня не было проблем с Tomcat / Jetty. Я не думаю, что у вас должны возникнуть проблемы с каким-либо контейнером, старым или новым.

public void close() throws IOException
    {
        if (_closed)
            return;

        if (!isIncluding() && !_generator.isCommitted())
            commitResponse(HttpGenerator.LAST);
        else
            flushResponse();

        super.close();
    }

Также как разработчик Фильтра вы не должны предполагать, что OutputStream не закрыт, вы всегда должны передавать другой OutputStream, если хотите изменить содержимое после того, как сервлет выполнил свою работу.

EDIT: Я всегда закрывал поток, и у меня не было проблем с Tomcat / Jetty. Я не думаю, что у вас должны возникнуть проблемы с каким-либо контейнером, старым или новым.

4
ответ дан 24 November 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: