webentwicklung-frage-antwort-db.com.de

Spring Boot entfernen Whitelabel-Fehlerseite

Ich versuche, die White-Label-Fehlerseite zu entfernen. Also habe ich 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

Weiß nicht, ob ich etwas falsch mache. Bitte beraten.

BEARBEITEN: 

Schon hinzugefügt error.whitelabel.enabled=false in die Datei "application.properties", wobei immer noch derselbe Fehler angezeigt wird

129

Sie müssen Ihren Code folgendermaßen ä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 BasicErrorController automatisch als Spring Bean registriert, wenn Sie keine Implementierung von ErrorController angegeben haben. 

Um dies zu sehen, navigieren Sie einfach zu ErrorMvcAutoConfiguration.basicErrorControllerhier .

209
geoand

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

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

Spring boot doc 'war' falsch (seitdem haben sie es behoben):

Um sie auszuschalten, können Sie error.whitelabel.enabled = false setzen

sollte sein 

Um es auszuschalten, können Sie server.error.whitelabel.enabled = false setzen

30
willome

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 dadurch wahrscheinlich 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.

30
hoodieman

Manuell hier sagt, dass Sie server.error.whitelabel.enabled auf false setzen müssen, um die Standardfehlerseite zu deaktivieren. Vielleicht ist es das, was du willst?

Der gleiche Fehler tritt übrigens nach dem Hinzufügen/Fehler-Mapping auf.

15
Innot Kauker

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.

11
db80

Dies hängt von Ihrer Springboot-Version ab:

Wenn SpringBootVersion <= 1.2, dann error.whitelabel.enabled = false verwenden

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

6
sendon1982

In Spring Boot 1.4.1 mit Mustache-Templates reicht es aus, error.html unter den Templates zu setzen:

<!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 /error erstellt wird.

5
Ecmel Ercan

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

Fügen Sie dies einfach zu 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"));
    }

}

Dann können Sie die Fehlerseiten normal im statischen Inhalt definieren.

Der Customizer kann auf Wunsch auch ein separater @Component sein.

2
rustyx

server.error.whitelabel.enabled = false

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

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

1

Ich habe versucht, einen REST Endpunkt von einem Microservice aufzurufen, und ich habe die put -Methode von resttemplate verwendet.

Wenn in meinem Design ein Fehler innerhalb des REST Endpunkts auftrat, sollte er eine JSON-Fehlerantwort zurückgeben, er funktionierte für einige Aufrufe, jedoch nicht für diesen put, Stattdessen wurde die White-Label-Fehlerseite zurückgegeben.

Also habe ich Nachforschungen angestellt und das herausgefunden.

Spring versucht, den Aufrufer zu verstehen, wenn es sich um eine Maschine handelt, dann gibt sie eine JSON-Antwort zurück oder wenn es sich um einen Browser handelt, dann gibt sie die White-Label-Fehlerseite HTML zurück.

Als Ergebnis: Meine Client-App musste dem REST Endpunkt mitteilen, dass der Anrufer ein Computer und kein Browser ist. Daher musste die Client-App ' application/json 'explizit in den ACCEPT-Header für die' put'-Methode des Resttemplates. Ich fügte dies dem Header hinzu und löste das Problem.

mein Anruf zum Endpunkt:

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

für den obigen Aufruf musste ich unter Header Parameter hinzufügen.

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

oder ich habe auch versucht, put to exchange zu ändern, in diesem Fall fügte exchange call den gleichen Header für mich hinzu und löste das Problem auch, aber ich weiß nicht warum :)

restTemplate.exchange(....)
1
cazador

Ich verwende Spring Boot Version 2.1.2 und die errorAttributes.getErrorAttributes()-Signatur funktionierte für mich nicht (in Akhens Antwort). Ich wollte eine Antwort vom Typ JSON, also habe ich ein wenig gesucht und festgestellt, dass diese Methode genau das tat, was ich brauchte. 

Die meisten meiner Informationen erhielt ich aus diesem Thread sowie aus diesem Blogpost

Zuerst habe ich eine CustomErrorController erstellt, 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 CustomHttpErrorResponse-Klasse 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.properties-Datei deaktivieren. 

server.error.whitelabel.enabled=false

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

0
David House