【问题标题】:Not able to throw error from response filter无法从响应过滤器中抛出错误
【发布时间】:2021-08-06 11:07:21
【问题描述】:

我正在尝试实现一个过滤器来修改我的 api 响应的响应。我也有一些过滤器来修改我的请求,效果很好。

下面是我的过滤器

public class ResponseFilter implements Filter {
    private static final Logger LOGGER = LogManager.getLogger(ResponseFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        chain.doFilter(request, response);
        httpResponse.sendError(HttpStatus.SC_BAD_REQUEST, "Error while extract....");
    }

}

过滤注册 Bean

@Configuration
public class FilterBean {
    private static final Logger LOGGER = LogManager.getLogger(FilterBean.class);
    
    @Value("${filter.urls}")
    private String filterUrls;

    @Bean
    public FilterRegistrationBean<ResponseFilter> responseFilter() {
        FilterRegistrationBean<ResponseFilter> registrationBean = new FilterRegistrationBean<>();
        LOGGER.debug("Inside responseFilter Bin....*********");
        registrationBean.setFilter(new ResponseFilter());
        registrationBean.addUrlPatterns(filterUrls.split(","));

        return registrationBean;
    }
}

以下是例外

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
    at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:456) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
    at com.example.filter.ResponseFilter.doFilter(ResponseFilter.java:41) ~[classes/:?]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.8.jar:5.3.8]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]

有人可以帮我在响应到达调用者之前拦截它。

【问题讨论】:

  • 如果将sendError() 调用移到chain.doFilter() 之前会发生什么?
  • 它将作为请求过滤器工作,并在我的控制器执行之前执行。我想拦截响应
  • 最好使用ResponseEntityExceptionHandler 扩展控制器类。用@ControllerAdvice注解这个类,写一个方法来处理你要拦截的异常。这个方法必须用@ExceptionHandler(YourException.class)注解。例如:@ExceptionHandler(Exception.class) private ResponseEntity handleAndLogRuntimeExceptions(Exception exception){。您还可以创建一个自定义异常,以防出现常规异常。然后,在此自定义异常中,您可以包装任何您想要作为响应返回的数据。

标签: java spring-boot filter


【解决方案1】:

通常,调用doFilter 意味着ServletRequestServletResponse 被传递给下一个过滤器(在FilterChain 对象中)。因此,当您尝试 sendError 时,您会得到 Cannot call sendError() after the response has been committed(您已经通过 doFilter 提交了响应)。

因此,如果您希望将请求传递给控制器​​并返回 HttpStatus.BAD_REQUEST,据我所知,您不能这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多