2017-02-22 14 views
0

В нашем приложении мы используем @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 и, следовательно, проблема неизбежна.

+0

В ходе дальнейшего исследования мы удалили класс '@ ControllerAdvice' и файл шаблона' error.html', чтобы увидеть, позволяет ли это добавить добавленный ErrorPage, но затем страница ошибки White-label для '404' отображается вместо настраиваемой страницы. Это указывает на то, что конфигурация компонента «ConfigurableEmbeddedServletContainer» может быть той, которая не дает желаемых результатов. –

+0

Можете ли вы предоставить [минимальный, полный, проверяемый пример] (/ help/mcve) для проблемы? –

+0

@ AndyWilkinson - Полный код приведен в разделе EDIT выше. Пожалуйста, дайте мне знать, если этого недостаточно. –

ответ

0

В весеннем ботинке 1.5.1 есть , что означает, что ErrorPageFilter регистрируется всякий раз, когда вы подклассом SpringBootServletInitializer. Он должен быть зарегистрирован только при упаковке приложения в качестве войны и развертывании его в автономном контейнере.Этот нежелательный фильтр разрушает вашу конфигурацию страницы пользовательской ошибки. Исправлена ​​ошибка в 1.5.2.

+0

Спасибо за подтверждение –