简体   繁体   English

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

[英]How to Read httpservletresponse inside Spring interceptor?

I'm working on task that log api request and response in database. 我正在执行将api请求和响应记录在数据库中的任务。 I need to autowire spring beans to access database and we can not autowire spring beans inside filter. 我需要自动装配spring bean才能访问数据库,而我们不能自动装配filter中的spring bean。

Problem is we can read response multiple times only in filter using HttpServletResponseWrapper. 问题是我们只能使用HttpServletResponseWrapper在过滤器中读取响应多次。

Is there any way to read response multiple times in spring interceptor? 在Spring拦截器中,有什么方法可以多次读取响应?

Here is my code using Filter . 这是我使用Filter的代码。 It can retrieve all information but can't autowire beans in ApiActivityManager to insert data in database. 它可以检索所有信息,但不能在ApiActivityManager中自动装配bean以在数据库中插入数据。

If I read response in Interceptor once then in controller response is null. 如果我一次在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() {

    }
}

Thanks 谢谢

To autowire spring beans in the filter class, 要自动过滤器类中的spring bean,

  1. first add @Component annotation in your filter class. 首先在过滤器类中添加@Component批注。
  2. Register filter with filter name as bean name and filter class as org.springframework.web.filter.DelegatingFilterProxy 将过滤器名称注册为bean名称,过滤器类注册为org.springframework.web.filter.DelegatingFilterProxy

So my solution is looks like, 所以我的解决方案看起来像

ApiActivityFilter.java 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() {

    }
}

Register filter using Java config 使用Java配置注册过滤器

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

Register filter using XML config 使用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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM