我有一个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。对于上述例外情况,我找到了许多解决方案,但在我的情况下却没有解决问题。