Ответ 1
Если я правильно вас понимаю, вы хотите зарегистрировать ответ тело? Это довольно дорогостоящая задача, но если это деловое требование...
Как показано на рисунке, a Filter
является подходящим местом для этого. Вы можете захватить тело ответа, заменив переданный ServletResponse
на HttpServletResponseWrapper
, который заменяет HttpServletResponse#getWriter()
собственной реализацией который копирует тело ответа в некоторый буфер. После продолжения цепи фильтра с замененным ответом просто запишите копию.
Вот пример запуска, как выглядит метод doFilter()
:
public void doFilter(ServletRequest request, final ServletResponse response, FilterChain chain) throws IOException, ServletException {
final CopyPrintWriter writer = new CopyPrintWriter(response.getWriter());
chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
@Override public PrintWriter getWriter() {
return writer;
}
});
logger.log(writer.getCopy());
}
Вот как выглядит CopyPrintWriter
:
public class CopyPrintWriter extends PrintWriter {
private StringBuilder copy = new StringBuilder();
public CopyPrintWriter(Writer writer) {
super(writer);
}
@Override
public void write(int c) {
copy.append((char) c); // It is actually a char, not an int.
super.write(c);
}
@Override
public void write(char[] chars, int offset, int length) {
copy.append(chars, offset, length);
super.write(chars, offset, length);
}
@Override
public void write(String string, int offset, int length) {
copy.append(string, offset, length);
super.write(string, offset, length);
}
public String getCopy() {
return copy.toString();
}
}
Сопоставьте этот фильтр с url-pattern
, для которого вы хотите регистрировать ответы. Имейте в виду, что бинарный/статический контент, такой как изображения, CSS, JS файлы и т.д., Не будет регистрироваться таким образом. Вы хотите исключить их, используя достаточно определенное значение url-pattern
, например. *.jsp
или только на servlet-name
рассматриваемого сервлета. Если вы хотите в любом случае записывать бинарный/статический контент (для которого я не вижу никакой пользы), вам нужно также заменить HttpServletResponse#getOutputStream()
.