Springboot 1.5.1升级-MVC异常处理问题



在我们的应用程序中,我们使用 @ControllerAdvice@ExceptionHandler处理各种 exceptions,并将其报告为INTERNAL_SERVER_ERROR如下:

@ControllerAdvice
public class ControllerExceptionHandler {
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public String handleAllExceptions() {
        return "error";
    }
}

除此之外,我们还可以处理NOT_FOUND使用ConfigurableEmbeddedServletContainer BEAN的应用程序的例外,以返回自定义的 pagenotfound 模板如下:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("home");
        registry.addViewController("/404").setViewName("pageNotFound");
    }
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return (container) -> container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
                                                                "/404"));
    }

这一切都可以正常工作,直到SBSP 1.4.x版本,但是自从我们将应用程序迁移到SBSP 1.5.1以来,NOT_FOUND处理程序被打破了,并且该应用程序现在从上面的@ExceptionHandler返回根据handleAllExceptions返回所配置的自定义错误页面。<<<<<<<<<<<<

目前尚不清楚ConfigurableEmbeddedServletContainer配置的行为是否有1.5.1以来的行为发生变化,但是配置不像以前那样工作,就像@controllerAdvice看起来像接管我们代码中的所有404处理程序的所有异常处理程序。<<<<<<<<<<<<<<<<<<<<<<<<<</p>

任何建议或指导都会有助于了解原因和解决方案/解决方法。

感谢ADV!

----编辑----

正如安迪建议的那样,请在下面找到证明问题/行为的示例项目。

应用程序类

@SpringBootApplication
public class NotFoundApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(NotFoundApplication.class, args);
    }
    @Configuration
    public static class WebConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/404").setViewName("pageNotFound");
        }
        @Bean
        public EmbeddedServletContainerCustomizer containerCustomizer() {
            return (container) -> container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
                    "/404"));
        }
    }
}

测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = NotFoundApplication.class,
        webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
public class NotFoundPageIT extends FluentTest {
    private WebDriver webDriver = new HtmlUnitDriver();
    @Value("${local.server.port}")
    private int port;
    @Page
    private NotFoundPage notFoundPage;
    @Override
    public WebDriver getDefaultDriver() {
        return webDriver;
    }
    @Override
    public String getDefaultBaseUrl() {
        return "http://localhost:" + port;
    }
    @Test
    public void showPageNotFoundWhenEndPointDoesNotExist() throws Exception {
        goTo("/notFound");
        notFoundPage.isAt();
    }
    public static class NotFoundPage extends FluentPage {
        @Override
        public void isAt() {
            assertThat(title()).contains("404 Page Unavailable");
            assertThat(find("body").getText()).contains("The requested page is not found");
        }
    }
}

html模板

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta charset="UTF-8" />
    <title>404 Page Unavailable</title>
</head>
<body>
   <h1>The requested page is not found</h1>
</body>
</html>

最简单的验证方法是运行代码库中存在的测试用例。

要寻找的主要测试是-showPageNotFoundWhenEndPointDoesNotExist,它解释了正在测试的行为。该测试将通过Spring Boot 1.4.4.Release版本进行运行,但是当版本升级到最新的1.5.1.Release。

时,失败。

要注意的另一个要点是,如果从SpringbootApplication注释类中删除extends SpringBootServletInitializer,则测试案例将通过并且行为是预期的。这可能进一步有助于零到潜在的有问题的领域。

对于我们的完整用户酶,我们需要扩展SpringBootServletInialializer,因此问题是不可避免的。

Spring Boot 1.5.1中有一个错误,这意味着每当您子类SpringBootServletInitializer时都会注册ErrorPageFilter。仅当您将应用程序打包为战争并将其部署到独立容器时,才应注册。此不需要的过滤器正在破坏您的自定义错误页面配置。该错误将在1.5.2中固定。

最新更新