2010-01-28 67 views
26

我正在嘗試記錄(只是爲了簡單起見,現在就寫控制檯編寫)HttpServletResponse將返回的最終呈現HTML。 (即身體)。爲此,我使用的是HandlerInterceptorAdapter從Spring MVC中,像這樣:使用Spring MVC從HttpServletResponse記錄響應正文(HTML)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響應頭。我的問題是,是否有一種相對簡單的方法可以將整個響應主體(即最終呈現的HTML)記錄到控制檯,而無需通過PrintWriters,OutputStream等進行跳轉千斤頂。

在此先感謝。

+0

這通常使用的幫助下完成容器......你在做什麼? – skaffman 2010-01-28 23:17:58

+0

我通過jetty-maven-plugin在Jetty 7中運行它,但我不明白爲什麼這應該很重要。我希望看到瀏覽器將收到的html響應。 – csamuel 2010-01-28 23:35:57

回答

21

這將使用一個Servlet Filter,而不是一個春天HandlerInterceptor可以做得更好,對於一個Filter允許替代請求和/或響應對象的原因,你可以利用這一機制來代替用包裝材料的響應它記錄了響應輸出。

這將涉及編寫HttpServletResponseWrapper的子類,覆蓋getOutputStream(也可能包括getWriter())。這些方法將返回OutputStream/PrintWriter實現,將響應流虹吸到日誌中,併發送到其原始目標。一個簡單的方法是從Apache Commons IO使用TeeOutputStream,但實現自己並不困難。

這裏是那種你可以做的事情的一個例子,利用Spring的GenericFilterBeanDelegatingServletResponseStream,以及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; 
    } 
} 

這一切都記錄到標準輸出。如果你想登錄到一個文件,它會變得更加複雜,確保流被關閉等等,但是原理仍然是一樣的。

+0

事實上,它確實變得更復雜,因爲在容器關閉流時,封裝不在範圍之外,因爲close沒有在DelegatingServletOutputStream上被調用。關於如何去做這件事的任何想法? – Ellis 2010-12-22 18:03:43

9

如果您使用(或考慮)logback作爲您的日誌框架,那麼已經有一個很好的servlet過濾器可以完全實現這一點。檢出documentation中的TeeFilter章節。

6

我一直在尋找一種方法來記錄完整的HTTP請求/響應一段時間,並發現它已被解決了我在Tomcat 7 RequestDumperFilter。它的工作原理與Tomcat 7容器一樣。如果你想在Jetty中使用它,這個類可以很好地獨立運行,或者像我一樣,可以複製並適應環境的特定需求。

+0

看起來這個過濾器也包含在這個答案中:http://stackoverflow.com/questions/5672904/replacement-for-re- quesdumpervalve-in-tomcat-7。 – 2012-10-30 20:01:07

+1

給Twiggs先生,Tomcat 7 RequestDumperFilter只能轉儲頭文件,這很簡單。 – Justin 2014-07-16 14:51:55

1

我做了一個小型圖書館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> 
相關問題