web-dev-qa-db-fra.com

Spring Boot et page d'erreur 404 personnalisée

Dans mon application Spring Boot, j'essaie de configurer des pages d'erreur personnalisées. Par exemple, pour 404, j'ai ajouté un bean suivant à la configuration de mon application:

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

De plus, j'ai créé un modèle simple de Thymeleaf suivant:

<!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>

et l'a ajouté dans le dossier /resources/templates/. À l'heure actuelle, sur l'erreur 404, je ne vois qu'un écran blanc.

Qu'est-ce que je fais de mal et comment configurer correctement ma page 404? En outre, est-il possible d'utiliser des modèles et pas uniquement des pages statiques pour des pages d'erreur personnalisées?

24
brunoid

Dans Spring Boot 1.4.x, vous pouvez ajouter une page d'erreur personnalisée :

Si vous souhaitez afficher une page d'erreur HTML personnalisée pour un code d'état donné, vous ajoutez un fichier à un dossier /error. Les pages d'erreur peuvent être du code HTML statique (c'est-à-dire ajoutées sous l'un des dossiers de ressources statiques) ou créées à l'aide de modèles. Le nom du fichier doit correspondre au code d’état exact ou à un masque de série.

Par exemple, pour mapper 404 sur un fichier HTML statique, la structure de votre dossier devrait ressembler à ceci:

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

Vous utilisez Thymeleaf, et Thymeleaf peut gérer les erreurs sans contrôleur. 

Pour une page d'erreur générique, cette page Thymeleaf doit être nommée error.html
et devrait être placé sous src/main/resources > templates > error.html

Thymleaf error.html

Pour des pages d'erreur spécifiques, vous devez créer des fichiers nommés comme code d'erreur http dans un dossier nommé error, tel que: src/main/resources/templates/error/404.html.

21
GoutamS

Si vous utilisez Thymeleaf comme suggéré dans la question, vous pouvez utiliser un modèle similaire à celui de la réponse précédente, mais approprié pour Thymeleaf plutôt que Freemarker. J'ai également ajouté bootstrap pour le style:

<!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>

Vous devez placer ce code dans un fichier appelé error.html et le placer dans votre répertoire de modèles de thymeleaf. Il n'est pas nécessaire d'ajouter un contrôleur supplémentaire pour que cela fonctionne.

4
OlgaMaciaszek

new ErrorPage (HttpStatus.NOT_FOUND, " /404.html ")

Ce /404.html représente le URL Path to Redirect, pas le nom du modèle. Puisque vous insistez pour utiliser un modèle, vous devez créer un contrôleur qui gère le /404.html et restitue votre 404.html dans le src/main/resources/templates:

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

Vous pouvez aussi remplacer ces contrôleurs de visualisation par un contrôleur de vues View:

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

En outre, est-il possible d'utiliser des modèles et pas seulement des pages statiques pour pages d'erreur personnalisées?

Oui c'est possible. Mais les pages Introuvables sont généralement statiques et l'utilisation d'un modèle au lieu de Plain Old HTMLs n'aurait pas beaucoup de sens.

4
Ali Dehghani

Le haricot EmbeddedServletContainerCustomizer n'est pas nécessaire. Il suffit de placer la page d'erreur correspondante (telle que 404.html dans le cas de 404) dans le répertoire public (cela est indiqué par @brunoid).

Notez également que vous pouvez également placer une page générique error.html à afficher chaque fois que votre application rencontre une erreur ou une exception.

Un exemple simple (dans 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>

Cela affichera le statut d'erreur et le message d'erreur correspondant. Et puisque vous utilisez Spring Boot, vous pouvez toujours remplacer les messages d’état et d’erreur affichés sur votre page d’erreur. 

4
Naiyer

Nous devons ajouter un nouveau 

 @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 peut gérer les erreurs sans contrôleur . Créer error.html dans le dossier des ressources.

0
sujoydutta