2014-11-04 243 views
1

我正在處理數據庫中記錄api請求和響應的任務。我需要autowire spring bean來訪問數據庫,而且我們不能在過濾器中自動調用spring beans。如何在Spring攔截器中讀取httpservletresponse?

問題是我們只能在使用HttpServletResponseWrapper的過濾器中多次讀取響應。

有沒有什麼辦法在spring攔截器中多次讀取響應?

這是我的代碼使用過濾器。它可以檢索所有信息,但不能在ApiActivityManager中自動調用bean以將數據插入到數據庫中。

如果我在Interceptor中讀取響應一次,那麼在控制器響應中爲null。

public class ApiActivityInterceptor implements Filter { 
    ApiActivityManager apiActivityManager = new ApiActivityManager(); 

    @Override public void init(FilterConfig filterConfig) throws ServletException { 
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     MyRequestWrapper requestWrapper = new MyRequestWrapper((HttpServletRequest)request); 
     MyResponseWrapper responseWrapper = new MyResponseWrapper((HttpServletResponse)response); 
     InputStream inputStream = requestWrapper.getInputStream(); 
     StringBuilder stringBuilder = new StringBuilder(); 
     BufferedReader bufferedReader = null; 
     if (inputStream != null) { 
      bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 
      char[] charBuffer = new char[128]; 
      int bytesRead = -1; 
      while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { 
       stringBuilder.append(charBuffer, 0, bytesRead); 
      } 
     } else { 
      stringBuilder.append(""); 
     } 
     String requestText = stringBuilder.toString(); 
     log.info(requestText); 

     chain.doFilter((ServletRequest)requestWrapper,(ServletResponse)responseWrapper); 

     String responseText = new String(responseWrapper.getCopy(),responseWrapper.getCharacterEncoding()); 
     log.info(responseText); 
     //for log details in database 
     activityLogDetails.setActivityLog(requestText,responseText); 
    } 

    @Override public void destroy() { 

    } 
} 

感謝

+0

你** **可以自動裝配豆過濾器。你必須使用'DelegatingFilterProxy'。 – zeroflagL 2014-11-04 16:06:55

+0

你能解決這個問題嗎?我面臨同樣的問題。 – n3o 2015-05-29 12:46:18

+0

@ n3o,我已經解決了它。我會在今天發佈答案。 – Piyush 2015-05-30 16:30:31

回答

0

自動裝配春豆在過濾器類,

  1. 先在過濾器類中添加註釋@Component
  2. 帶過濾器的名字作爲bean的名字和org.springframework.web.filter.DelegatingFilterProxy

所以我的解決方案看起來像過濾器類註冊過濾器,

ApiActivityFilter.java

@Component("apiActivityFilter") 
public class ApiActivityFilter implements Filter { 

    @Autowired 
    ApiActivityManager apiActivityManager; 

    @Override public void init(FilterConfig filterConfig) throws ServletException { 
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     MyRequestWrapper requestWrapper = new MyRequestWrapper((HttpServletRequest)request); 
     MyResponseWrapper responseWrapper = new MyResponseWrapper((HttpServletResponse)response); 
     InputStream inputStream = requestWrapper.getInputStream(); 
     StringBuilder stringBuilder = new StringBuilder(); 
     BufferedReader bufferedReader = null; 
     if (inputStream != null) { 
      bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 
      char[] charBuffer = new char[128]; 
      int bytesRead = -1; 
      while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { 
       stringBuilder.append(charBuffer, 0, bytesRead); 
      } 
     } else { 
      stringBuilder.append(""); 
     } 
     String requestText = stringBuilder.toString(); 
     log.info(requestText); 

     chain.doFilter((ServletRequest)requestWrapper,(ServletResponse)responseWrapper); 

     String responseText = new String(responseWrapper.getCopy(),responseWrapper.getCharacterEncoding()); 
     log.info(responseText); 
     //for log details in database 
     apiActivityManager.logApiActivity(activityLog);//activityLog Object to be logged 
    } 

    @Override public void destroy() { 

    } 
} 

使用寄存器過濾器Java配置

FilterRegistration.Dynamic apiActivityFilter = servletContext.addFilter("apiActivityFilter", DelegatingFilterProxy.class); 
apiActivityFilter.addMappingForUrlPatterns(null, true, "/api/*"); 

使用XML配置寄存器濾波器

<filter> 
    <filter-name>apiActivityFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>apiActivityFilter</filter-name> 
    <url-pattern>/api/*</url-pattern> 
</filter-mapping>