HttpServletResponseによって返される最終的にレンダリングされたHTMLをログに記録しようとしています(簡単にするために、今すぐコンソールに書き込みます)。 (つまり、本体)この目的のために、SpringMVCのHandlerInterceptorAdapterを次のように使用しています。
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応答ヘッダーが表示されます。私の質問は、PrintWritersやOutputStreamなどでジャンプジャックを行うことなく、応答本文全体(つまり、最終的にレンダリングされたHTML)をコンソールに記録する比較的簡単な方法があるかどうかです。
前もって感謝します。
これは、Filter
という理由で、Spring HandlerInterceptor
ではなくサーブレット Filter
を使用して行う方が適切です。は、要求オブジェクトや応答オブジェクト、あるいはその両方を置き換えることができます。このメカニズムを使用して、応答を、応答出力をログに記録するラッパーに置き換えることができます。
これには、 HttpServletResponseWrapper
のサブクラスを記述し、getOutputStream
(および場合によってはgetWriter()
)をオーバーライドすることが含まれます。これらのメソッドは、元の宛先に送信するだけでなく、応答ストリームをログに吸い上げるOutputStream
/PrintWriter
実装を返します。これを行う簡単な方法は、 TeeOutputStream
from 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に記録されます。ファイルにログを記録する場合は、ストリームを確実に閉じるなど、さらに複雑になりますが、原則は同じです。
しばらくの間、完全なHTTP要求/応答をログに記録する方法を探していましたが、 Tomcat 7 RequestDumperFilter で解決されていることがわかりました。 Tomcat7コンテナからアドバタイズされたとおりに機能します。 Jettyで使用する場合は、クラスはスタンドアロンで正常に機能するか、私が行ったように、環境の特定のニーズに合わせてコピーおよび適合させます。
小さなライブラリを作成しました spring-mvc-logger mavencentralから利用できます。
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>