Как я могу прочитать поток вывода HttpServletReponses? - PullRequest
26 голосов
/ 31 марта 2009

Я хочу создать фильтр сервлетов, который будет считывать содержимое ответа после его обработки и завершения и возвращать эту информацию в формате XML, PDF или как угодно. Но я не уверен, как получить какую-либо информацию из объекта HttpServletResponse. Как я могу получить эту информацию?

Ответы [ 4 ]

29 голосов
/ 31 марта 2009

Добавьте это в java-файл фильтра.

static class MyHttpServletResponseWrapper 
  extends HttpServletResponseWrapper {

  private StringWriter sw = new StringWriter(BUFFER_SIZE);

  public MyHttpServletResponseWrapper(HttpServletResponse response) {
    super(response);
  }

  public PrintWriter getWriter() throws IOException {
    return new PrintWriter(sw);
  }

  public ServletOutputStream getOutputStream() throws IOException {
    throw new UnsupportedOperationException();
  }

  public String toString() {
    return sw.toString();
  }
}

Используйте следующий код:

HttpServletResponse httpResponse = (HttpServletResponse) response;
MyHttpServletResponseWrapper wrapper = 
  new MyHttpServletResponseWrapper(httpResponse);

chain.doFilter(request, wrapper);

String content = wrapper.toString();

Переменная содержимого теперь имеет выходной поток. Вы также можете сделать это для двоичного содержимого.

3 голосов
/ 14 апреля 2017

Spring теперь имеет функцию для этого. Все, что вам нужно сделать, это использовать [ContentCachingResponseWrapper], у которого есть метод public byte [] getContentAsByteArray ().

Предлагаю сделать WrapperFactory, который позволит сделать его настраиваемым, использовать ли по умолчанию ResponseWrapper или ContentCachingResponseWrapper.

1 голос
/ 31 марта 2009

Я не верю, что вы обязательно можете сделать это, учитывая, что запись в выходной поток может привести к тому, что данные будут сброшены клиенту до того, как какие-либо фильтры сервлета будут вызваны после заполнения. Как предполагает iftrue , для генерирования вашего XML (скажем) и последующей регенерации в любом выходном формате, который вы пожелаете, рекомендуется использовать другую архитектуру.

РЕДАКТИРОВАТЬ: прочитав ваш ответ на сообщение iftrue , если вы действительно не можете вмешиваться в текущую обработку, возможно, вам нужен сервлет для прокси-запроса вашего запроса, захват вывод из исходного вывода, а затем munge в зависимости от обстоятельств. Очень противно, однако: - (

1 голос
/ 31 марта 2009

Я не очень знаю, что вы можете получить данные из объекта HttpServletResponse как такового. Возможно, имеет смысл структурировать ваше приложение так, чтобы запросы передавались в соответствующие обработчики и передавались с объектами передачи данных, из которых вы можете создать соответствующий окончательный ответ. Таким образом, вы никогда не модифицируете более одного объекта ответа или не хотите читать из него.

Не прямой ответ, я знаю, но вот как я бы это сделал, чтобы задать вопрос.

...