Форма ответа журнала (HTML) из HttpServletResponse с использованием Spring MVC HandlerInterceptorAdapter
Я пытаюсь войти (просто для того, чтобы просто написать для простоты) окончательный визуализированный HTML, который будет возвращен HttpServletResponse. (т.е. тело). С этой целью я использую HandlerInterceptorAdapter из Spring MVC следующим образом:
public class VxmlResponseInterceptor extends HandlerInterceptorAdapter {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(response.toString());
}
}
Это работает как ожидалось, и я вижу заголовки HTTP-ответа в консоли. Мой вопрос в том, есть ли относительно простой способ зарегистрировать весь орган ответа (то есть конечный визуализированный HTML) на консоль, не прибегая к выполнению прыгающих гнезд с помощью PrintWriters, OutputStream и т.п.
Спасибо заранее.
Ответы
Ответ 1
Это лучше сделать с помощью сервлета Filter
, а не Spring HandlerInterceptor
, по той причине, что a Filter
разрешено заменять объекты запроса и/или ответа, и вы можете использовать этот механизм для подстановки ответа с помощью обертки, которая регистрирует вывод ответа.
Это будет связано с написанием подкласса HttpServletResponseWrapper
, переопределяя getOutputStream
(и, возможно, также getWriter()
). Эти методы будут возвращать реализации OutputStream
/PrintWriter
, которые отфильтровывают поток ответов в журнале, в дополнение к отправке в исходное место назначения. Простой способ сделать это - TeeOutputStream
из Apache Commons IO, но это не сложно реализовать самостоятельно.
Вот пример того, что вы могли бы сделать, используя Spring GenericFilterBean
и DelegatingServletResponseStream
, а также TeeOutputStream
, чтобы облегчить задачу:
public class ResponseLoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse responseWrapper = loggingResponseWrapper((HttpServletResponse) response);
filterChain.doFilter(request, responseWrapper);
}
private HttpServletResponse loggingResponseWrapper(HttpServletResponse response) {
return new HttpServletResponseWrapper(response) {
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new DelegatingServletOutputStream(
new TeeOutputStream(super.getOutputStream(), loggingOutputStream())
);
}
};
}
private OutputStream loggingOutputStream() {
return System.out;
}
}
Это записывает все в STDOUT. Если вы хотите войти в файл, это станет более сложным, что бы убедиться, что потоки закрыты и так далее, но принцип остается тем же.
Ответ 2
Если вы используете (или рассматриваете) logback в качестве своей рамки ведения журнала, есть уже хороший сервлет-фильтр, который точно выполняет что. Ознакомьтесь с разделом TeeFilter в документации.
Ответ 3
Я искал способ регистрации полного HTTP-запроса/ответа на некоторое время и обнаружил, что он был решен для меня в Tomcat 7 RequestDumperFilter. Он работает как рекламируемый из контейнера Tomcat 7. Если вы хотите использовать его в Jetty, класс работает отлично автономно или, как я, копировал и адаптировался к конкретным потребностям моей среды.
Ответ 4
Я сделал небольшую библиотеку spring-mvc-logger, доступную через центральный центр maven.
Добавить в pom.xml:
<dependency>
<groupId>com.github.isrsal</groupId>
<artifactId>spring-mvc-logger</artifactId>
<version>0.2</version>
</dependency>
Добавить в web.xml:
<filter>
<filter-name>loggingFilter</filter-name>
<filter-class>com.github.isrsal.logging.LoggingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loggingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Добавить в log4j.xml:
<logger name="com.github.isrsal.logging.LoggingFilter">
<level value="DEBUG"/>
</logger>