在我们的应用中使用@ControllerAdvice
和@ExceptionHandler
来处理所有类型的exceptions
和报告这些作为INTERNAL_SERVER_ERROR
如下:Springboot 1.5.1升级 - MVC异常处理问题
@ControllerAdvice
public class ControllerExceptionHandler {
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public String handleAllExceptions() {
return "error";
}
}
除此之外,我们也有处理程序照顾NOT_FOUND
例外使用ConfigurableEmbeddedServletContainer
豆返回如下定制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
所配置的自定义错误页面。
从1.5.1开始,配置ConfigurableEmbeddedServletContainer
的行为有变化,但配置不像以前那样工作,因为@ControllerAdvice看起来像是接管了所有异常处理程序,覆盖了代码中的404处理程序。
任何建议或指导将有助于了解原因和修复/解决方法。
谢谢!
---- ----编辑
至于建议由安迪请发现证明了问题/行为的一个示例项目下面。
App类
@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
,则测试用例会通过并且行为如预期。这可能会进一步帮助您解决潜在的问题领域。
对于我们的完整用例,我们需要扩展SpringBootServletInitializer,因此这个问题是不可避免的。
在进一步调查中,我们删除了'@ ControllerAdvice'类和'error.html'模板文件,以查看是否允许添加的ErrorPage起作用,但是404的白标签错误页面是显示而不是自定义页面。它表明,'ConfigurableEmbeddedServletContainer' bean配置可能是未能提供所需结果的配置。 –
您能否为此问题提供一个[最小,完整,可验证的示例](/ help/mcve)? –
@AndyWilkinson - 完整的代码在上面的编辑部分提供。请让我知道,如果它不够。 –