如何在Spring拦截器中读取httpservletresponse?

时间:2014-11-04 14:43:53

标签: java spring spring-mvc filter interceptor

我正在处理在数据库中记录api请求和响应的任务。我需要autowire spring bean来访问数据库,我们不能在过滤器内自动装配spring bean。

问题是我们只能在使用HttpServletResponseWrapper的过滤器中多次读取响应。

  

有没有办法在spring拦截器中多次读取响应?

以下是使用过滤器的代码。它可以检索所有信息,但不能在ApiActivityManager中自动装配bean以在数据库中插入数据。

如果我在Interceptor中读取一次响应,则控制器响应为空。

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() {

    }
}

由于

1 个答案:

答案 0 :(得分:0)

要在过滤器类中自动装配spring bean,

  1. 首先在过滤器类中添加@Component注释。
  2. 将过滤器名称作为bean名称注册过滤器,过滤器类名称为org.springframework.web.filter.DelegatingFilterProxy
  3. 所以我的解决方案看起来像,

    <强> 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>