Spring Загрузочная и пользовательская страница ошибок 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? Кроме того, возможно ли использовать шаблоны, а не только статические страницы для пользовательских страниц ошибок?
Ответы
Ответ 1
В Spring Boot 1.4.x вы можете добавить страницу пользовательских ошибок:
Если вы хотите отобразить страницу пользовательской HTML-ошибки для данного кода состояния, вы добавляете файл в папку /error
. Страницы ошибок могут быть статическими HTML (то есть добавлены в любую из статических каталогов ресурсов) или созданы с использованием шаблонов. Имя файла должно быть точным кодом состояния или маской серии.
Например, чтобы сопоставить 404 с статическим HTML файлом, ваша структура папок будет выглядеть так:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
Ответ 2
Вы используете Thymeleaf, а Thymeleaf может обрабатывать ошибки без контроллера.
Для общей страницы ошибок эту страницу Thymeleaf нужно назвать как error.html
и должен быть помещен в src/main/resources > templates > error.html
![Thymleaf error.html]()
Для определенных страниц ошибок вам необходимо создать файлы с именем http-кода ошибки в папке с именем error, например: src/main/resources/templates/error/404.html
.
Ответ 3
new 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";
}
}
Вы также можете заменить эти только просмотр контроллеров рендеринга-рендера контроллером вида:
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/404.html").setViewName("404");
}
}
Кроме того, можно ли использовать шаблоны, а не только статические страницы для пользовательские страницы ошибок?
Да, это возможно. Но не найденные страницы, как правило, статичны, и использование шаблона вместо обычных HTML-страниц не будет иметь большого смысла.
Ответ 4
Нет необходимости в EmbeddedServletContainerCustomizer
bean. Простое размещение соответствующей страницы ошибки (например, 404.html в случае 404) в общедоступном каталоге должно быть достаточно (как указано @brunoid).
Также обратите внимание, что вы также можете поместить общую страницу error.html
, которая будет отображаться всякий раз, когда ваше приложение сталкивается с ошибкой или исключением.
Простой пример (во Фримаркере) -
<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, вы всегда можете отменить сообщения о статусе и ошибках, отображаемые на странице ошибок.
Ответ 5
Если вы используете 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. Нет необходимости добавлять дополнительный контроллер для работы.
Ответ 6
Thymeleaf может обрабатывать ошибку без контроллера.
создайте папку errors.html в ресурсах.
Ответ 7
Мы должны добавить новый
@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";
}
}
Ответ 8
Проверьте, есть ли у вас в списке путей тимили, или добавьте приведенный ниже код и повторно импортируйте проект.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>