it-roy-ru.com

Spring Boot и пользовательская страница ошибки 404

В моем приложении Spring Boot я пытаюсь настроить пользовательские страницы ошибок, например, для 404, я добавил следующий компонент в конфигурацию своего приложения:

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/404.html"));
        }
    };
}

Кроме того, я создал следующий простой шаблон Thymeleaf:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>404 Not Found</title>
        <meta charset="utf-8" />
    </head>
    <body>
        <h3>404 Not Found</h3>
        <h1 th:text="${errorCode}">404</h1>
        <p th:utext="${errorMessage}">Error Java.lang.NullPointerException</p>
        <a href="/" th:href="@{/}">Back to Home Page</a>
    </body>
</html>

и добавил его в папку /resources/templates/. Прямо сейчас на ошибке 404 я вижу только белый экран.

Что я делаю не так и как правильно настроить мою страницу 404? Кроме того, возможно ли использовать шаблоны, а не только статические страницы для пользовательских страниц ошибок?

24
brunoid

В Spring Boot 1.4.x вы можете добавить настраиваемую страницу ошибок :

Если вы хотите отобразить пользовательскую страницу ошибки HTML для данного кода состояния, вы добавляете файл в папку /error. Страницы ошибок могут быть либо статическим HTML (то есть добавленным в любую из папок статического ресурса), либо созданным с использованием шаблонов. Имя файла должно быть точным кодом состояния или последовательной маской.

Например, чтобы отобразить 404 в статический HTML-файл, структура вашей папки будет выглядеть следующим образом:

src/
 +- main/
     +- Java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>
46
brunoid

Вы используете Thymeleaf, а Thymeleaf может обрабатывать ошибки без контроллера. 

Для общей страницы ошибок эту страницу Thymeleaf нужно назвать error.html
и должен быть помещен под src/main/resources > templates > error.html

Thymleaf error.html

Для определенных страниц ошибок вам необходимо создать файлы с именем http-кода ошибки в папке с именем error, например: src/main/resources/templates/error/404.html.

21
GoutamS

Если вы используете Thymeleaf, как предложено в вопросе, вы можете использовать шаблон, похожий на шаблон из предыдущего ответа, но подходящий для Thymeleaf, а не Freemarker. Я также добавил начальную загрузку для стиля:

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<head>
<title>Error Page</title>
<link href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css" rel="stylesheet" media="screen"/>
<script src="/webjars/jquery/3.2.1/jquery.min.js"></script>
<script src="/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="jumbotron alert-danger">
    <h1>Oops... something went wrong.</h1>
    <h2 th:text="${status + ' ' + error}"></h2>
</div>
</div>
</body>
</html>

Вы должны поместить этот код в файл с именем error.html и поместить его в каталог шаблонов thymeleaf. Нет необходимости добавлять дополнительный контроллер для его работы.

4
OlgaMaciaszek

новый ErrorPage (HttpStatus.NOT_FOUND, " /404.html ")

Этот /404.html представляет URL-путь к перенаправлению, а не имя шаблона. Поскольку вы настаиваете на использовании шаблона, вы должны создать контроллер, который обрабатывает /404.html и отображает ваш 404.html в src/main/resources/templates:

@Controller
public class NotFoundController {
    @RequestMapping("/404.html")
    public String render404(Model model) {
        // Add model attributes
        return "404";
    }
}

Вы также можете заменить эти просто контроллеры рендеринга на View Controller:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/404.html").setViewName("404");
    }
}

Также возможно ли использовать шаблоны, а не только статические страницы для пользовательские страницы ошибок?

Да, это возможно. Но страницы Not Found обычно статичны, и использование шаблона вместо Plain Old HTMLs не имеет особого смысла.

4
Ali Dehghani

В бине EmbeddedServletContainerCustomizer нет необходимости. Достаточно просто поместить соответствующую страницу ошибки (например, 404.html в случае 404) в публичный каталог (как указано @brunoid).

Также обратите внимание, что вы также можете разместить общую страницу error.html, которая будет отображаться всякий раз, когда ваше приложение обнаружит ошибку или исключение.

Простой пример (во Freemarker) -

<html lang="en">
<head>
</head>
<body>
    <div class="container">
        <div class="jumbotron alert-danger">
            <h1>Oops. Something went wrong</h1>
            <h2>${status} ${error}</h2>
        </div>
    </div>
</body>

</html>

Это покажет правильный статус ошибки и соответствующее сообщение об ошибке. А поскольку вы используете Spring Boot, вы всегда можете переопределить статус и сообщения об ошибках, которые отображаются на вашей странице ошибок. 

4
Naiyer

Мы должны добавить новый 

 @Controller
public class MyErrorController implements ErrorController  {

    @RequestMapping("/error")
public String handleError(HttpServletRequest request) {
    Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);

    if (status != null) {
        Integer statusCode = Integer.valueOf(status.toString());

        if(statusCode == HttpStatus.NOT_FOUND.value()) {
            return "error404";
        }
        else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
            return "error500";
        }
    }
    return "error";
}

    @Override
    public String getErrorPath() {
        return "/error";
    }
}
0
vipul gulhane

Thymeleaf может обрабатывать ошибки без контроллера . Создать error.html в папке ресурсов.

0
sujoydutta