java.lang.IllegalStateException:在实现过滤器时已为此请求调用getInputStream()

时间:2019-01-03 17:27:36

标签: file spring-boot servlets filter

我有一个Spring Boot应用程序,我想在其中基于URL调用过滤器。

@Bean
public FilterRegistrationBean filter1() {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setName("filter1");
    Filter1 filter1 = new Filter1();
    registrationBean.setFilter(filter1);
    registrationBean.setOrder(1);
    registrationBean.addUrlPatterns("/path1/path2");
    return registrationBean;
}

我的过滤器1如下:

public class Filter1 implements Filter {

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

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // Do required action
    }

    @Override
    public void destroy() {  }
}   

我的控制器方法如下:

@RequestMapping(value="/path1/path2", method = RequestMethod.POST)
public ResponseEntity<?> processFile(@RequestParam("file") MultipartFile file) {
    //......
}

我希望在调用上述API时调用Filter1过滤器。但我收到以下异常:

java.lang.IllegalStateException: getInputStream() has already been called for this request
    at org.apache.catalina.connector.Request.getReader(Request.java:1205)
    at org.apache.catalina.connector.RequestFacade.getReader(RequestFacade.java:504)
    at javax.servlet.ServletRequestWrapper.getReader(ServletRequestWrapper.java:225)
    at javax.servlet.ServletRequestWrapper.getReader(ServletRequestWrapper.java:225)
    at com.merck.nextconnect.authfilter.CustomRequestWrapper.getReader(CustomRequestWrapper.java:46)
    at com.merck.nextconnect.authfilter.InjectionFilter.doFilter(InjectionFilter.java:67)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at com.merck.nextconnect.authfilter.LogMdcFilter.doFilter(LogMdcFilter.java:36)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)

所以我尝试实现自定义ServletRequestWrapper,如下所示:

public class WrappedRequest extends ServletRequestWrapper {
    private String _body;
    private HttpServletRequest _request;

    public WrappedRequest(HttpServletRequest request) throws IOException {
        super(request);
        _request = request;

        _body = "";
        try (BufferedReader bufferedReader = request.getReader()) {
            String line;
            while ((line = bufferedReader.readLine()) != null)
                _body += line;
        }
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(_body.getBytes());
        return new ServletInputStream() {
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }

            @Override
            public boolean isFinished() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean isReady() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {
                // TODO Auto-generated method stub

            }
        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }
}

我仍然遇到同样的异常。控件根本不会转到WrappedRequest。对于上述例外情况,我找到了许多解决方案,但在我的情况下却没有解决问题。

0 个答案:

没有答案