Я хочу создать фильтр сервлета, который будет читать содержимое ответа после его обработки и завершения и возвращать эту информацию в формате XML или PDF или что-то еще. Но я не уверен, как получить какую-либо информацию из объекта HttpServletResponse. Как я могу получить эту информацию?
Как я могу прочитать поток вывода HttpServletReponses?
Ответы (4)
Добавьте это в 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();
Переменная содержимого теперь имеет выходной поток. Вы также можете сделать это для двоичного содержимого.
BUFFER_SIZE
?
- person asgs; 02.09.2015
Теперь у Spring есть функция для этого. Все, что вам нужно сделать, это использовать [ContentCachingResponseWrapper], у которого есть метод public byte[] getContentAsByteArray().
Предлагаю сделать WrapperFactory, который позволит сделать его настраиваемым, использовать ли ResponseWrapper по умолчанию или ContentCachingResponseWrapper.
Я мало знаю, что вы можете получить данные из объекта HttpServletResponse как такового. Возможно, имеет смысл структурировать ваше приложение таким образом, чтобы запросы передавались соответствующим обработчикам и передавались с объектами передачи данных, из которых вы можете построить соответствующий окончательный ответ. Таким образом, вы никогда не изменяете более одного объекта ответа и не должны читать из него.
Я знаю, что это не прямой ответ, но именно так я бы и задал вопрос.
Я не верю, что вы обязательно можете это сделать, учитывая, что запись в выходной поток может привести к тому, что данные будут сброшены на клиент до того, как какие-либо фильтры сервлета будут вызваны после заполнения. Как предполагает iftrue, рекомендуется использовать другую архитектуру, чтобы сгенерировать ваш XML (скажем), а затем регенерировать в любом желаемом формате вывода.
РЕДАКТИРОВАТЬ: прочитав ваш ответ на публикацию iftrue, если вы действительно не можете вмешиваться в текущую обработку, возможно, вам требуется сервлет для проксирования вашего запроса, захватите вывод из исходного вывода, а затем при необходимости имитировать. Очень противно, однако :-(