web-dev-qa-db-fra.com

Spring Boot Supprimer la page d'erreur Whitelabel

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

@RestController
public class IndexController {

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

}

Mais maintenant, je reçois 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.

MODIFIER: 

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

129
Yasitha Chinthaka

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 BasicErrorController en tant que bean Spring lorsque vous n'avez pas spécifié d'implémentation de ErrorController

Pour voir ce fait, il suffit de naviguer vers ErrorMvcAutoConfiguration.basicErrorControllerici .

209
geoand

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);
  }
}
40
acohen

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

Pour l'éteindre, vous pouvez définir error.whitelabel.enabled = false

devrait être 

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

30
willome

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, sachez que cela entraînera probablement l'affichage des pages de la balise blanche du conteneur de servlet :)


EDIT: Une autre façon de faire est via application.yaml. Il suffit de mettre dans la valeur:

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

Documentation

Pour Spring Boot <2.0, la classe est située dans le package org.springframework.boot.autoconfigure.web.

30
hoodieman

Manual here indique que vous devez définir server.error.whitelabel.enabled sur false pour désactiver la page d'erreur standard. Peut-être que c'est ce que tu veux?

En passant, je rencontre la même erreur après avoir ajouté/mappage d'erreur.

15
Innot Kauker

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.

11
db80

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

Lorsque SpringBootVersion <= 1.2, utilisez ensuite error.whitelabel.enabled = false

Lorsque SpringBootVersion > = 1.3, utilisez ensuite server.error.whitelabel.enabled = false

6
sendon1982

Dans Spring Boot 1.4.1 à l'aide de modèles Mustache, placer le fichier error.html dans le dossier des modèles suffit

<!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 passées en créant un intercepteur pour /error

5
Ecmel Ercan

Voici une méthode alternative très similaire à la "vieille méthode" de spécification de mappages d'erreur 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 les pages d'erreur dans le contenu statique normalement.

Le personnaliseur peut également être un @Component séparé, si vous le souhaitez.

2
rustyx

server.error.whitelabel.enabled = false

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

Plus Erreur Résolution résoudre s'il vous plaît se référer http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

1
suganya sudarsan

J'utilise la version 2.1.2 de Spring Boot et la signature errorAttributes.getErrorAttributes() ne fonctionnait pas pour moi (réponse donnée par acohen). Je voulais une réponse de type JSON, j'ai donc creusé un peu et découvert que cette méthode répondait exactement à mes besoins. 

La plupart de mes informations proviennent de ce fil ainsi que de ce blog post

Tout d'abord, j'ai créé une variable CustomErrorController que Spring cherchera pour mapper les erreurs éventuelles. 

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 classe CustomHttpErrorResponse pour renvoyer l'erreur en tant que 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 Whitelabel dans le fichier application.properties

server.error.whitelabel.enabled=false

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

0
David House

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

Dans ma conception, si une erreur quelconque se produisait dans le noeud final REST, elle devrait renvoyer une réponse d'erreur JSON, elle fonctionnait pour certains appels mais pas pour cette commande put one, elle renvoyait la page d'erreur étiquette blanche). au lieu. 

Alors j'ai fait une enquête et je l'ai découvert; 

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

En conséquence: mon application client devait indiquer au point de terminaison REST que l'appelant était une machine et non un navigateur. Pour cela, l'application client devait ajouter explicitement ' application/json ' 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 ci-dessous en-tête param.

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

ou j'ai essayé de changer de mettre à échanger aussi, dans ce cas, l'échange d'appel 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(....)
0
cazador