我们可以在Spring Boot中捕获Tomcat异常吗?

问题描述 投票:0回答:1
  • Java 21
  • Spring Boot 3.3.4
  • 嵌入式Tomcat

我有一个在嵌入式 Tomcat 上运行的 Spring Boot REST API。我使用

@ControllerAdvice
来自定义错误响应。在负面测试期间,我注意到,如果我故意发送格式错误的标头,我会在
o.apache.coyote.http11.Http11Processor   : Error parsing HTTP request header
中收到异常(如预期),但
@ControllerAdvice
不会拾取它。

是否可以在 Spring Boot 应用程序中捕获这些异常?

java spring spring-boot tomcat
1个回答
0
投票

在Spring Boot应用程序中,@ControllerAdvice用于在控制器中全局处理异常。不过,@ControllerAdvice 只能捕获 Spring MVC 处理链中的异常,而不能捕获 Tomcat 服务器解析 HTTP 请求头时发生的低级异常,例如解析 HTTP 请求头时出错。 要捕获这些异常,需要在较低级别进行处理,例如通过自定义 Tomcat 的 ErrorPage 或 ErrorPageFilter。以下是一个例子:

1.创建自定义ErrorPageFilter

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.filter.ErrorPageFilter;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
public class CustomErrorPageConfig {

    @Bean
    public FilterRegistrationBean<GenericFilterBean> errorPageFilter() {
        FilterRegistrationBean<GenericFilterBean> registration = new FilterRegistrationBean<>();
        registration.setFilter(new CustomErrorPageFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(1);
        return registration;
    }

    public static class CustomErrorPageFilter extends GenericFilterBean {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            try {
                chain.doFilter(request, response);
            } catch (IOException | ServletException e) {
                handleException((HttpServletRequest) request, (HttpServletResponse) response, e);
            }
        }

        private void handleException(HttpServletRequest request, HttpServletResponse response, Exception e) {
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            response.setContentType("application/json");
            response.getWriter().write("{\"error\": \"Invalid request header\"}");
            response.getWriter().flush();
        }
    }
}

2.配置错误页面

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

@Configuration
public class ErrorPageConfig implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        ErrorPage error400Page = new ErrorPage(HttpStatus.BAD_REQUEST, "/error");
        registry.addErrorPages(error400Page);
    }
}

3.创建错误处理控制器

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ErrorController {

    @RequestMapping("/error")
    public ResponseEntity<String> handleError() {
        return new ResponseEntity<>("Invalid request header", HttpStatus.BAD_REQUEST);
    }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.