В нашем приложении мы используем @ControllerAdvice
и @ExceptionHandler
обрабатывать все виды exceptions
и сообщать о тех, как INTERNAL_SERVER_ERROR
, как показано ниже:Springboot 1.5.1 Upgrade - MVC Exception Handling Проблемы
@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
сломан, и приложение теперь возвращает настроенную страницу с измененной ошибкой в соответствии с handleAllExceptions
от @ExceptionHandler
выше.
Непонятно, есть ли изменения в конфигурации конфигурации ConfigurableEmbeddedServletContainer
с 1.5.1, но конфигурация не работает по-прежнему, поскольку @ControllerAdvice выглядит как захват всех обработчиков исключений, охватывающих обработчик 404 в нашем коде.
Любые предложения или рекомендации помогут узнать причину и исправить/обходной путь.
Благодарим вас за консультацию!
---- EDIT ----
Как было предложено Энди, пожалуйста, найти ниже проекта образца, который доказывает выпуск/поведение.
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.
Другим недостатком является то, что если extends SpringBootServletInitializer
удален из аннотированного класса SpringBootApplication, тестовый пример пройдет, и поведение будет таким, как ожидалось. Это может также помочь свести к нулю потенциальную проблемную область.
Для нашей полной утилиты нам необходимо расширить SpringBootServletInitializer и, следовательно, проблема неизбежна.
В ходе дальнейшего исследования мы удалили класс '@ ControllerAdvice' и файл шаблона' error.html', чтобы увидеть, позволяет ли это добавить добавленный ErrorPage, но затем страница ошибки White-label для '404' отображается вместо настраиваемой страницы. Это указывает на то, что конфигурация компонента «ConfigurableEmbeddedServletContainer» может быть той, которая не дает желаемых результатов. –
Можете ли вы предоставить [минимальный, полный, проверяемый пример] (/ help/mcve) для проблемы? –
@ AndyWilkinson - Полный код приведен в разделе EDIT выше. Пожалуйста, дайте мне знать, если этого недостаточно. –