Spring Boot Whitelabel-Fehlerseite entfernen

155

Ich versuche, die White-Label-Fehlerseite zu entfernen. Ich habe also eine Controller-Zuordnung für "/ error" erstellt.

@RestController
public class IndexController {

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

}

Aber jetzt bekomme ich diesen Fehler.

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

Ich weiß nicht, ob ich etwas falsch mache. Bitte beraten.

BEARBEITEN:

Wurde bereits error.whitelabel.enabled=false zur Datei application.properties hinzugefügt und erhält immer noch den gleichen Fehler

Yasitha Waduge
quelle
1
Schauen Sie sich dieses Projekt an. Github.com/paulc4/mvc-exceptions/blob/master/src/main/java/… scheint eine Fehlerseiten-Neuzuordnung zu haben.
Innot Kauker
Haben Sie versucht einzustellen spring.resources.add-mappings=false?
Geo und
Vielen Dank für den Vorschlag, Ja, immer noch den gleichen Fehler
Yasitha Waduge
Versuchen Sie nur, benutzerdefinierten Inhalt zurückzugeben, wenn der /errorPfad aufgerufen wird?
Geo und

Antworten:

239

Sie müssen Ihren Code wie folgt ändern:

@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;
    }
}

Ihr Code hat nicht funktioniert, da Spring Boot das automatisch BasicErrorControllerals Spring Bean registriert, wenn Sie keine Implementierung von angegeben haben ErrorController.

Um diese Tatsache zu sehen, navigieren Sie einfach ErrorMvcAutoConfiguration.basicErrorController hierher .

geoand
quelle
1
Ich bin auf dasselbe Problem gestoßen und habe die Spring-Dokumente durchsucht, aber BasicErrorController wurde nicht erwähnt. Das funktioniert :)
Mike R
4
Ich musste die Quelle durchgehen, um diese zu finden :-)
geoand
1
Danke, hat gut funktioniert! Ein kleines Follow-up, wenn Sie Hinweise geben können: Angenommen, wir erhalten diesen Fehlerbehandler, weil in unserer App eine Ausnahme ausgelöst wurde (und Spring den Antwortcode implizit auf 500 setzt, was korrekt ist). Gibt es hier eine einfache Möglichkeit, diese Ausnahme zu erreichen (um einige Details in die zurückgegebene Fehlermeldung aufzunehmen)?
Jonik
1
Ich bin froh, dass du es nützlich fandest! Obwohl ich es nicht ausprobiert habe, bin ich mir ziemlich sicher, dass Sie die Prinzipien von Spring Boot BasicErrorController(siehe github.com/spring-projects/spring-boot/blob/… ) verwenden können, um das zu erreichen, was Sie wollen
geoand
3
Hmm, ja, nochmals vielen Dank! Zuerst war ich mir nicht sicher, wie ich dieses ErrorAttributesObjekt bekommen sollte (das die Fehlerdetails enthält), aber dann habe ich es einfach mit @Autowiring versucht und es funktioniert. Was ich jetzt gemacht habe: gist.github.com/jonikarppinen/662c38fb57a23de61c8b
Jonik
44

Wenn Sie eine "JSONish" -Antwortseite wünschen, können Sie Folgendes ausprobieren:

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);
  }
}
akustisch
quelle
7
In Spring-Boot v2 befinden sich die Klassen ErrorController und ErrorAttributes im Paket org.springframework.boot.web.servlet.error. Außerdem hat sich die Signatur der ErrorAttributes # getErrorAttributes-Methode geändert. Beachten Sie die Abhängigkeit von Spring-Boot v1 und geben Sie möglicherweise Hinweise für v2 an. Vielen Dank.
Chrisinmtown
1
Änderung: private Map <String, Object> getErrorAttributes (HttpServletRequest aRequest, boolean includeStackTrace) {RequestAttributes requestAttributes = new ServletRequestAttributes (aRequest); return errorAttributes.getErrorAttributes (requestAttributes, includeStackTrace); } Von: private Map <String, Object> getErrorAttributes (HttpServletRequest-Anforderung, boolesches includeStackTrace) {WebRequest webRequest = new ServletWebRequest (Anforderung); return this.errorAttributes.getErrorAttributes (webRequest, includeStackTrace); }
Rija Ramampiandra
2
Eine aktualisierte Version von SimpleErrorController.java unter Berücksichtigung der Kommentare von oben finden Sie hier> gist.github.com/oscarnevarezleal/…
Oscar Nevarez
38

Spring Boot Doc 'war' falsch (sie haben es seitdem behoben):

Zum Ausschalten können Sie error.whitelabel.enabled = false setzen

sollte sein

Zum Ausschalten können Sie server.error.whitelabel.enabled = false festlegen

willome
quelle
Dadurch wird die White-Label-Fehlerseite deaktiviert, aber der Frühlingsstart ordnet den Endpunkt /errortrotzdem zu. Um den Endpunkt frei /errorSatz server.error.path=/error-springoder einen alternativen Weg.
Notizen-jj
32

Sie können es vollständig entfernen, indem Sie Folgendes angeben:

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

Beachten Sie jedoch, dass dies wahrscheinlich dazu führt, dass stattdessen die Whitelabel-Seiten des Servlet-Containers angezeigt werden :)


BEARBEITEN: Eine andere Möglichkeit, dies zu tun, ist über application.yaml. Geben Sie einfach den Wert ein:

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

Dokumentation

Bei Spring Boot <2.0 befindet sich die Klasse im Paket org.springframework.boot.autoconfigure.web.

Hoodieman
quelle
15

Handbuch hier sagt , dass Sie setzen müssen , server.error.whitelabel.enabledum falsedie Standard - Fehlerseite zu deaktivieren. Vielleicht ist es was du willst?

Ich habe übrigens den gleichen Fehler nach dem Hinzufügen / Fehler-Mapping.

Innot Kauker
quelle
Ja, ich habe bereits error.whitelabel.enabled = false gesetzt, erhalte aber nach dem Hinzufügen / Fehler-Mapping immer noch den gleichen Fehler
Yasitha Waduge
Dadurch wird die White-Label-Fehlerseite deaktiviert, aber der Frühlingsstart ordnet den Endpunkt /errortrotzdem zu. Um den Endpunkt frei /errorSatz server.error.path=/error-springoder einen alternativen Weg.
Notizen-jj
11

Mit Spring Boot> 1.4.x können Sie Folgendes tun:

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

Im Ausnahmefall zeigt der Servlet-Container jedoch eine eigene Fehlerseite an.

db80
quelle
8

Dies hängt von Ihrer Spring Boot-Version ab:

Wenn SpringBootVersion <= 1.2dann verwendenerror.whitelabel.enabled = false

Wenn SpringBootVersion > =, 1.3dann verwenden Sieserver.error.whitelabel.enabled = false

sendon1982
quelle
6

In Spring Boot 1.4.1 mit Moustache-Vorlagen reicht es aus, error.html im Vorlagenordner abzulegen:

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

Zusätzliche Variablen können übergeben werden, indem ein Interceptor für erstellt wird /error

Ecmel Ercan
quelle
3

Hier ist eine alternative Methode, die der "alten Methode" zum Festlegen von Fehlerzuordnungen in sehr ähnlich ist web.xml.

Fügen Sie dies einfach Ihrer Spring Boot-Konfiguration hinzu:

@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"));
    }

}

Anschließend können Sie die Fehlerseiten im statischen Inhalt normal definieren.

@ComponentFalls gewünscht, kann der Customizer auch ein separater sein .

Rustyx
quelle
3

Ich verwende Spring Boot Version 2.1.2 und die errorAttributes.getErrorAttributes()Signatur hat bei mir nicht funktioniert (in der Antwort von Acohen). Ich wollte eine Antwort vom Typ JSON, also grub ich ein wenig und stellte fest, dass diese Methode genau das tat, was ich brauchte.

Ich habe die meisten meiner Informationen aus diesem Thread sowie aus diesem Blog-Beitrag erhalten .

Zuerst habe ich eine erstellt CustomErrorController, nach der Spring suchen wird, um Fehler zuzuordnen.

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;
    }
}

Zweitens habe ich eine CustomHttpErrorResponseKlasse erstellt, um den Fehler als JSON zurückzugeben.

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
}

Schließlich musste ich das Whitelabel in der application.propertiesDatei deaktivieren .

server.error.whitelabel.enabled=false

Dies sollte sogar für xmlAnfragen / Antworten funktionieren . Aber das habe ich nicht getestet. Es hat genau das getan, wonach ich gesucht habe, seit ich eine RESTful-API erstellt habe und nur JSON zurückgeben wollte.

DJ House
quelle
2

server.error.whitelabel.enabled = false

Fügen Sie die obige Zeile in die Ressourcenordner application.properties ein

Weitere Informationen zur Fehlerbehebung finden Sie unter http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

Suganya Sudarsan
quelle
Ich habe application.properties in meinem Installationsordner ausprobiert, was nichts bewirkt hat. Der Ordner application.properties unter / src / main / resources ist das, was suganya sudarsan zu vermitteln versuchte. Es scheint auch in Eclipse ein "heißes Lesen" zu sein.
Richard Bradley Smith
1

Ich habe versucht, einen REST-Endpunkt von einem Microservice aus aufzurufen, und die put- Methode des Resttemplates verwendet.

Wenn in meinem Entwurf ein Fehler innerhalb des REST-Endpunkts aufgetreten ist, sollte eine JSON-Fehlerantwort zurückgegeben werden. Es funktionierte für einige Aufrufe, aber nicht für diesen Put- Aufruf. Es wurde die White-Label-Fehlerseite zurückgegeben Stattdessen wurde .

Also habe ich Nachforschungen angestellt und das herausgefunden.

Spring versucht, den Aufrufer zu verstehen, wenn es sich um einen Computer handelt, der eine JSON-Antwort zurückgibt, oder wenn es sich um einen Browser handelt, gibt er den HTML- Code der White-Label-Fehlerseite zurück .

Als Ergebnis: Meine Client-App musste dem REST-Endpunkt mitteilen, dass der Aufrufer ein Computer und kein Browser ist. Daher musste die Client-App ' application / json ' explizit für die 'put'-Methode des Resttemplates in den ACCEPT-Header einfügen. Ich habe dies zum Header hinzugefügt und das Problem gelöst.

Mein Anruf beim Endpunkt:

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

Für den obigen Aufruf musste ich den folgenden Header-Parameter hinzufügen.

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

oder ich habe versucht, put to exchange ebenfalls zu ändern. In diesem Fall hat der Exchange-Aufruf den gleichen Header für mich hinzugefügt und das Problem ebenfalls gelöst, aber ich weiß nicht warum :)

restTemplate.exchange(....)
Cazador
quelle
0

Spring Boot verfügt standardmäßig über eine Whitelabel- Fehlerseite, die in einem Browser angezeigt wird, wenn ein Serverfehler auftritt. Die Whitelabel-Fehlerseite ist eine generische Spring Boot-Fehlerseite, die angezeigt wird, wenn keine benutzerdefinierte Fehlerseite gefunden wird.

Setzen Sie "server.error.whitelabel.enabled = false", um die Standardfehlerseite zu wechseln

Shatakshi
quelle
0

Ich hatte ein ähnliches Problem mit der WhiteLabel-Fehlermeldung in meinem Angular SPA, wenn ich eine Aktualisierung durchführte.

Das Update bestand darin, einen Controller zu erstellen, der ErrorController implementiert. Statt jedoch einen String zurückzugeben, musste ich ein ModelAndView-Objekt zurückgeben, das an / weiterleitet

@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
quelle