2014-11-04 244 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>