Я попытаюсь ответить на более конкретный вопрос, поднятый в вашем примере:
Рассмотрим сторонний фильтр, который украшает выходные данные запроса и получает OutputStream. Как фильтр или сервлет, который должен работать с Writer, должен «знать», что OutputStream уже открыт, и должно ли это заботиться?
Servlet API также запрещает использование Writer и OutputStream при заполнении ответа, как указано в документации API для метода ServletResponse.getWriter () :
Либо этот метод, либо getOutputStream () могут быть вызваны для записи тела, а не оба.
Если фильтр (сторонний или другой) хочет записать ответ, особенно после того, как сервлеты его сгенерировали, он должен предположить, что
- сервлет использовал либо Writer, либо OutputStream для заполнения ответа.
- сервлет вызвал бы метод
close()
для Writer или объекта OutputStream.
Чтобы учесть это, фильтр должен создать экземпляр HttpServletResponseWrapper , передать его вниз по потоку в сервлет для заполнения, снова прочитать его, а затем заполнить фактический объект HttpServletResponse, управляемый контейнером.
Вышесказанное также было бы в силе, если бы фильтр сначала заполнил ответ (до дальнейшей обработки запроса). Он должен выполнить заполнение фактического объекта HttpServletResponse, передать обертку вниз по течению, а затем записать содержимое обертки в фактический объект.