Page d'erreur Spring Boot Remove Whitelabel

156

J'essaie de supprimer la page d'erreur en marque blanche, donc j'ai créé un mappage de contrôleur pour "/ error",

@RestController
public class IndexController {

    @RequestMapping(value = "/error")
    public String error() {
        return "Error handling";
    }

}

Mais maintenant, j'obtiens cette erreur.

Exception in thread "AWT-EventQueue-0" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource   [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Invocation  of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'basicErrorController' bean method 
public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>>  org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletR equest)
to {[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'indexController' bean method

Je ne sais pas si je fais quelque chose de mal. S'il vous plaît des conseils.

ÉDITER:

Déjà ajouté error.whitelabel.enabled=false au fichier application.properties, toujours la même erreur

Yasitha Waduge
la source
1
Regardez ce projet github.com/paulc4/mvc-exceptions/blob/master/src/main/java/… , il semble qu'ils contiennent un remappage de page d'erreur.
Innot Kauker
Avez-vous essayé le réglage spring.resources.add-mappings=false?
geoand
Merci pour la suggestion, Oui a toujours la même erreur
Yasitha Waduge
Essayez-vous simplement de renvoyer du contenu personnalisé lorsque le /errorchemin est appelé?
geoand

Réponses:

240

Vous devez modifier votre code comme suit:

@RestController
public class IndexController implements ErrorController{

    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public String error() {
        return "Error handling";
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

Votre code n'a pas fonctionné, car Spring Boot enregistre automatiquement le en BasicErrorControllertant que Spring Bean lorsque vous n'avez pas spécifié d'implémentation de ErrorController.

Pour voir ce fait, accédez simplement à ErrorMvcAutoConfiguration.basicErrorController ici .

geoand
la source
1
Ran dans le même dans le même problème, j'ai cherché les documents Spring mais il n'a pas mentionné BasicErrorController. Cela fonctionne :)
Mike R
4
J'ai dû passer par la source pour trouver celui-ci :-)
geo et
1
Merci, a bien fonctionné! Un petit suivi si vous pouvez donner des pointeurs: disons que nous obtenons ce gestionnaire d'erreurs car une exception a été lancée dans notre application (et Spring définit implicitement le code de réponse à 500, ce qui est correct); y a-t-il un moyen facile d'obtenir cette exception ici (pour inclure certains détails dans le message d'erreur renvoyé)?
Jonik
1
Content que vous ayez trouvé ça utile! Bien que je ne l'ai pas essayé, je suis presque sûr que vous pouvez utiliser les principes trouvés dans Spring Boot BasicErrorController(voir github.com/spring-projects/spring-boot/blob/… ) pour accomplir ce que vous voulez
geo et
3
Hmm, oui, merci encore! Au début, je ne savais pas comment obtenir cet ErrorAttributesobjet (contenant les détails de l'erreur), mais j'ai ensuite essayé simplement @Autowiring, et cela fonctionne. Ce que je suis allé avec pour l'instant: gist.github.com/jonikarppinen/662c38fb57a23de61c8b
Jonik
44

Si vous voulez une page de réponse plus "JSONish", vous pouvez essayer quelque chose comme ça:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@RestController
@RequestMapping("/error")
public class SimpleErrorController implements ErrorController {

  private final ErrorAttributes errorAttributes;

  @Autowired
  public SimpleErrorController(ErrorAttributes errorAttributes) {
    Assert.notNull(errorAttributes, "ErrorAttributes must not be null");
    this.errorAttributes = errorAttributes;
  }

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

  @RequestMapping
  public Map<String, Object> error(HttpServletRequest aRequest){
     Map<String, Object> body = getErrorAttributes(aRequest,getTraceParameter(aRequest));
     String trace = (String) body.get("trace");
     if(trace != null){
       String[] lines = trace.split("\n\t");
       body.put("trace", lines);
     }
     return body;
  }

  private boolean getTraceParameter(HttpServletRequest request) {
    String parameter = request.getParameter("trace");
    if (parameter == null) {
        return false;
    }
    return !"false".equals(parameter.toLowerCase());
  }

  private Map<String, Object> getErrorAttributes(HttpServletRequest aRequest, boolean includeStackTrace) {
    RequestAttributes requestAttributes = new ServletRequestAttributes(aRequest);
    return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
  }
}
acohen
la source
7
Dans Spring-Boot v2, les classes ErrorController et ErrorAttributes sont dans le package org.springframework.boot.web.servlet.error et en outre, la signature de la méthode ErrorAttributes # getErrorAttributes a changé, veuillez noter la dépendance à Spring-Boot v1 et éventuellement donner des conseils pour la v2, THX.
chrisinmtown
1
Changement: mappe privée <chaîne, objet> getErrorAttributes (HttpServletRequest aRequest, boolean includeStackTrace) {RequestAttributes requestAttributes = new ServletRequestAttributes (aRequest); return errorAttributes.getErrorAttributes (requestAttributes, includeStackTrace); } Par: private Map <String, Object> getErrorAttributes (requête HttpServletRequest, booléen includeStackTrace) {WebRequest webRequest = new ServletWebRequest (requête); return this.errorAttributes.getErrorAttributes (webRequest, includeStackTrace); }
Rija Ramampiandra
2
Une version mise à jour de SimpleErrorController.java compte tenu des commentaires ci-dessus peut être trouvée ici> gist.github.com/oscarnevarezleal
Oscar Nevarez
38

Le document de démarrage de printemps `` était '' faux (ils l'ont depuis corrigé):

Pour le désactiver, vous pouvez définir error.whitelabel.enabled = false

devrait être

Pour le désactiver, vous pouvez définir server.error.whitelabel.enabled = false

Willome
la source
Cela désactivera la page d'erreur White Label mais Spring Boot mappera /errorquand même le point final . Pour libérer l' /errorensemble de points de terminaison server.error.path=/error-springou un chemin alternatif.
notes-jj
32

Vous pouvez le supprimer complètement en spécifiant:

import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
...
@Configuration
@EnableAutoConfiguration(exclude = {ErrorMvcAutoConfiguration.class})
public static MainApp { ... }

Cependant, notez que cela entraînera probablement l'affichage des pages de marque blanche du conteneur de servlet à la place :)


EDIT: Une autre façon de faire est via application.yaml. Mettez simplement la valeur:

spring:
  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration

Documentation

Pour Spring Boot <2.0, la classe se trouve dans package org.springframework.boot.autoconfigure.web.

hoodieman
la source
15

Le manuel indique ici que vous devez définir server.error.whitelabel.enabledsur falsepour désactiver la page d'erreur standard. C'est peut-être ce que tu veux?

Au fait, je rencontre la même erreur après l'ajout / le mappage d'erreur.

Innot Kauker
la source
Oui, j'ai déjà défini error.whitelabel.enabled = false mais j'obtiens toujours la même erreur après l'ajout / le mappage d'erreur
Yasitha Waduge
Cela désactivera la page d'erreur White Label mais Spring Boot mappera /errorquand même le point final . Pour libérer l' /errorensemble de points de terminaison server.error.path=/error-springou un chemin alternatif.
notes-jj
11

Avec Spring Boot> 1.4.x, vous pouvez faire ceci:

@SpringBootApplication(exclude = {ErrorMvcAutoConfiguration.class})
public class MyApi {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

mais en cas d'exception, le conteneur de servlet affichera sa propre page d'erreur.

db80
la source
8

Cela dépend de votre version de démarrage de printemps:

Lorsque SpringBootVersion <= 1.2alors utilisezerror.whitelabel.enabled = false

Lorsque SpringBootVersion > = 1.3alors utilisezserver.error.whitelabel.enabled = false

sendon1982
la source
6

Dans Spring Boot 1.4.1 en utilisant les modèles Moustache, placer error.html dans le dossier des modèles suffira:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Error</title>
</head>

<body>
  <h1>Error {{ status }}</h1>
  <p>{{ error }}</p>
  <p>{{ message }}</p>
  <p>{{ path }}</p>
</body>

</html>

Des variables supplémentaires peuvent être transmises en créant un intercepteur pour /error

Ecmel Ercan
la source
3

Voici une méthode alternative qui est très similaire à la "vieille méthode" de spécification des mappages d'erreurs dans web.xml.

Ajoutez simplement ceci à votre configuration Spring Boot:

@SpringBootApplication
public class Application implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        factory.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN, "/errors/403.html"));
        factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/errors/404.html"));
        factory.addErrorPages(new ErrorPage("/errors/500.html"));
    }

}

Ensuite, vous pouvez définir normalement les pages d'erreur dans le contenu statique.

Le personnalisateur peut également être un élément distinct @Component, si vous le souhaitez.

rustyx
la source
3

J'utilise Spring Boot version 2.1.2 et la errorAttributes.getErrorAttributes()signature n'a pas fonctionné pour moi (en réponse à une réponse de Cohen). Je voulais une réponse de type JSON alors j'ai creusé un peu et j'ai trouvé que cette méthode faisait exactement ce dont j'avais besoin.

J'ai obtenu la plupart de mes informations de ce fil ainsi que de ce billet de blog .

Tout d'abord, j'ai créé un CustomErrorControllerque Spring recherchera pour mapper les erreurs.

package com.example.error;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@RestController
public class CustomErrorController implements ErrorController {

    private static final String PATH = "error";

    @Value("${debug}")
    private boolean debug;

    @Autowired
    private ErrorAttributes errorAttributes;

    @RequestMapping(PATH)
    @ResponseBody
    public CustomHttpErrorResponse error(WebRequest request, HttpServletResponse response) {
        return new CustomHttpErrorResponse(response.getStatus(), getErrorAttributes(request));
    }

    public void setErrorAttributes(ErrorAttributes errorAttributes) {
        this.errorAttributes = errorAttributes;
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }

    private Map<String, Object> getErrorAttributes(WebRequest request) {
        Map<String, Object> map = new HashMap<>();
        map.putAll(this.errorAttributes.getErrorAttributes(request, this.debug));
        return map;
    }
}

Deuxièmement, j'ai créé une CustomHttpErrorResponseclasse pour renvoyer l'erreur au format JSON.

package com.example.error;

import java.util.Map;

public class CustomHttpErrorResponse {

    private Integer status;
    private String path;
    private String errorMessage;
    private String timeStamp;
    private String trace;

    public CustomHttpErrorResponse(int status, Map<String, Object> errorAttributes) {
        this.setStatus(status);
        this.setPath((String) errorAttributes.get("path"));
        this.setErrorMessage((String) errorAttributes.get("message"));
        this.setTimeStamp(errorAttributes.get("timestamp").toString());
        this.setTrace((String) errorAttributes.get("trace"));
    }

    // getters and setters
}

Enfin, j'ai dû désactiver l'étiquette blanche dans le application.propertiesfichier.

server.error.whitelabel.enabled=false

Cela devrait même fonctionner pour les xmldemandes / réponses. Mais je n'ai pas testé cela. Il a fait exactement ce que je recherchais depuis que je créais une API RESTful et que je voulais uniquement renvoyer JSON.

DJ House
la source
2

server.error.whitelabel.enabled = false

Incluez la ligne ci-dessus dans les dossiers de ressources application.properties

Plus de résolution des problèmes d'erreur, veuillez vous référer à http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

suganya sudarsan
la source
J'ai essayé application.properties dans mon dossier d'installation qui n'a rien fait. Le dossier application.properties sous / src / main / resources est ce que suganya sudarsan tentait de transmettre. Il semble également être une "lecture à chaud" dans Eclipse.
Richard Bradley Smith le
1

J'essayais d'appeler un point de terminaison REST à partir d'un microservice et j'utilisais la méthode put du resttemplate .

Dans ma conception si une erreur a été commise dans le REST point final , il doit renvoyer une réponse d'erreur JSON, il travaillait pour certains appels mais pas pour ce mettre un, il est retourné à la page d'erreur de marque blanche à la place.

J'ai donc fait une enquête et j'ai découvert cela;

Spring essaie de comprendre l'appelant s'il s'agit d'une machine, puis il renvoie une réponse JSON ou s'il s'agit d'un navigateur, il renvoie la page d'erreur en marque blanche HTML.

En conséquence: mon application client devait dire au point de terminaison REST que l'appelant est une machine, pas un navigateur, donc pour cela, l'application client doit ajouter ' application / json explicitement '' dans l'en-tête ACCEPT pour la méthode `` put '' du resttemplate. J'ai ajouté ceci à l'en-tête et résolu le problème.

mon appel au point final:

restTemplate.put(url, request, param1, param2);

pour l'appel ci-dessus, j'ai dû ajouter le paramètre d'en-tête ci-dessous.

headers.set("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);

ou j'ai essayé de changer de mise en échange également, dans ce cas, l'appel d'échange a ajouté le même en-tête pour moi et a résolu le problème aussi mais je ne sais pas pourquoi :)

restTemplate.exchange(....)
cazador
la source
0

Spring Boot a par défaut une page d'erreur « whitelabel » que vous pouvez voir dans un navigateur si vous rencontrez une erreur de serveur. La page d'erreur Whitelabel est une page d'erreur Spring Boot générique qui s'affiche lorsqu'aucune page d'erreur personnalisée n'est trouvée.

Définissez "server.error.whitelabel.enabled = false" pour basculer vers la page d'erreur par défaut

shatakshi
la source
0

J'ai eu un message d'erreur WhiteLabel similaire sur mon SPA angulaire chaque fois que je faisais une actualisation.

Le correctif consistait à créer un contrôleur qui implémente ErrorController, mais au lieu de renvoyer une chaîne, je devais renvoyer un objet ModelAndView qui transfère vers /

@CrossOrigin
@RestController
public class IndexController implements ErrorController {
    
    private static final String PATH = "/error";
    
    @RequestMapping(value = PATH)
    public ModelAndView saveLeadQuery() {           
        return new ModelAndView("forward:/");
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}
Shubhashish Mishra
la source