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

标签 java spring spring-mvc filter interceptor

我正在处理在数据库中记录 api 请求和响应的任务。我需要 Autowiring spring bean 来访问数据库,但我们无法在过滤器内 Autowiring spring bean。

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

Is there any way to read response multiple times in spring interceptor?

这是我使用过滤器的代码。它可以检索所有信息,但无法在 ApiActivityManager 中 Autowiring bean 以将数据插入数据库。

如果我在拦截器中读取响应一次,则 Controller 响应为空。

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

    }
}

谢谢

最佳答案

要在过滤器类中 Autowiring spring beans,

  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>

关于java - 如何在Spring拦截器中读取httpservletresponse?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26737981/

相关文章:

java - 相同的值多次添加到数据库中

一个应用程序中的 Spring Security OAuth2 和 FormLogin

spring - Spring MVC 4 的 Controller 配置无效

java - 我的@Cacheable 似乎被忽略了( Spring )

java - 如何从 Instant 和时间字符串构造 ZonedDateTime?

java - 我如何在 Java 中舍入货币值?

java - 在 ScrollPane 中滚动时,图形会从 Canvas 中删除

Java 密码和 php mcrypt_encrypt(带 ECB 填充的 BLOWFISH 算法)

java - Spring启动找不到HIBERNATE_SEQUENCE

javascript - Apache Tomcat 错误 : 404 page not found while the other jsp runs properly