Spring Boot Rimuovere la pagina di errore Whitelabel


156

Sto cercando di rimuovere la pagina di errore dell'etichetta bianca, quindi quello che ho fatto è stato creato una mappatura del controller per "/ errore",

@RestController
public class IndexController {

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

}

Ma ora sto ricevendo questo errore.

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

Non so se sto facendo qualcosa di sbagliato. Per favore, consiglio.

MODIFICARE:

Già aggiunto error.whitelabel.enabled=false al file application.properties, ottenendo ancora lo stesso errore


1
Guarda questo progetto github.com/paulc4/mvc-exceptions/blob/master/src/main/java/… , sembra che abbiano una pagina di errore rimappata in esso.
Innot Kauker,

Hai provato a impostare spring.resources.add-mappings=false?
geoand,

Grazie per il suggerimento, Sì, ho ancora ricevuto lo stesso errore
Yasitha Waduge,

Stai solo cercando di restituire alcuni contenuti personalizzati quando /errorviene chiamato il percorso?
geoand,

Risposte:


240

Devi modificare il tuo codice nel modo seguente:

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

Il tuo codice non ha funzionato, perché Spring Boot registra automaticamente BasicErrorControllercome Spring Bean quando non hai specificato un'implementazione di ErrorController.

Per vedere questo fatto basta andare ErrorMvcAutoConfiguration.basicErrorController qui .


1
Mi sono imbattuto nello stesso nello stesso problema, ho cercato i documenti di Spring ma non ha menzionato BasicErrorController. Funziona :)
Mike R

4
Ho dovuto consultare la fonte per trovare questo :-)
geoand

1
Grazie, ha funzionato bene! Un piccolo follow-up se puoi dare qualche suggerimento: supponiamo di avere questo gestore degli errori perché nella nostra app è stata generata un'eccezione (e Spring imposta implicitamente il codice di risposta su 500 che è corretto); c'è un modo semplice per ottenere questa eccezione qui (per includere alcuni dettagli nel messaggio di errore restituito)?
Jonik,

1
Mi fa piacere che l'abbia trovato utile! Anche se non l'ho provato, sono abbastanza sicuro che puoi usare i principi trovati in Spring Boot's BasicErrorController(vedi github.com/spring-projects/spring-boot/blob/… ) per realizzare quello che vuoi
geoand

3
Hmm, sì, grazie ancora! All'inizio non ero sicuro di come ottenere ErrorAttributesquell'oggetto (contenente i dettagli dell'errore), ma poi ho provato semplicemente @Autowiring e funziona. Per cosa sono andato per ora: gist.github.com/jonikarppinen/662c38fb57a23de61c8b
Jonik,

44

Se vuoi una pagina di risposta più "JSONish" puoi provare qualcosa del genere:

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

7
In Spring-Boot v2 le classi ErrorController ed ErrorAttributes si trovano nel pacchetto org.springframework.boot.web.servlet.error e inoltre la firma del metodo ErrorAttributes # getErrorAttributes è cambiata, notare la dipendenza da Spring-Boot v1 e possibilmente dare suggerimenti per v2, grazie.
chrisinmtown,

1
Modifica: mappa privata <String, Object> getErrorAttributes (HttpServletRequest aRequest, boolean includeStackTrace) {RequestAttributes requestAttributes = new ServletRequestAttributes (aRequest); return errorAttributes.getErrorAttributes (requestAttributes, includeStackTrace); } By: private Map <String, Object> getErrorAttributes (richiesta HttpServletRequest, booleano includeStackTrace) {WebRequest webRequest = new ServletWebRequest (richiesta); return this.errorAttributes.getErrorAttributes (webRequest, includeStackTrace); }
Rija Ramampiandra,

2
Una versione aggiornata di SimpleErrorController.java considerando i commenti sopra può essere trovata qui> gist.github.com/oscarnevarezleal/…
Oscar Nevarez,

38

Il documento di avvio di Spring "era" errato (da allora lo hanno risolto):

Per disattivarlo è possibile impostare error.whitelabel.enabled = false

dovrebbe essere

Per disattivarlo è possibile impostare server.error.whitelabel.enabled = false


Ciò disabiliterà la Pagina di errore dell'etichetta bianca ma l'avvio a molla mapperà /errorcomunque l'endpoint . Per liberare il /errorset di endpoint server.error.path=/error-springo un percorso alternativo.
notes-jj

32

Puoi rimuoverlo completamente specificando:

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

Tuttavia, tieni presente che farlo causerà probabilmente la visualizzazione delle pagine whitelabel del container servlet :)


EDIT: Un altro modo per farlo è tramite application.yaml. Inserisci il valore:

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

Documentazione

Per Spring Boot <2.0, la classe si trova nel pacchetto org.springframework.boot.autoconfigure.web.


15

Manuale qui dice che è necessario impostare server.error.whitelabel.enabledper falsedisabilitare la pagina di errore standard. Forse è quello che vuoi?

A proposito, sto riscontrando lo stesso errore dopo aver aggiunto / mappatura degli errori.


Sì, ho già impostato error.whitelabel.enabled = false ma ricevo ancora lo stesso errore dopo l'aggiunta / mappatura degli errori
Yasitha Waduge,

Ciò disabiliterà la Pagina di errore dell'etichetta bianca ma l'avvio a molla mapperà /errorcomunque l'endpoint . Per liberare il /errorset di endpoint server.error.path=/error-springo un percorso alternativo.
notes-jj

11

Con Spring Boot> 1.4.x puoi fare questo:

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

ma poi in caso di eccezione il contenitore servlet mostrerà la propria pagina di errore.



6

In Spring Boot 1.4.1 utilizzando i modelli Moustache, sarà sufficiente posizionare error.html nella cartella dei modelli:

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

È possibile passare ulteriori variabili creando un intercettore per /error



3

Ecco un metodo alternativo che è molto simile al "vecchio modo" di specificare le mappature degli errori web.xml.

Basta aggiungere questo alla configurazione di 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"));
    }

}

Quindi è possibile definire normalmente le pagine di errore nel contenuto statico.

Il personalizzatore può anche essere separato @Component, se lo si desidera.


3

Sto usando Spring Boot versione 2.1.2 e la errorAttributes.getErrorAttributes()firma non ha funzionato per me (nella risposta di acohen). Volevo una risposta di tipo JSON, quindi ho fatto un po 'di ricerche e ho scoperto che questo metodo ha fatto esattamente ciò di cui avevo bisogno.

Ho ricevuto la maggior parte delle mie informazioni da questa discussione e da questo post sul blog .

Innanzitutto, ho creato un oggetto CustomErrorControllerche Spring cercherà di mappare eventuali errori.

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

In secondo luogo, ho creato una CustomHttpErrorResponseclasse per restituire l'errore come 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
}

Alla fine, ho dovuto disattivare la Whitelabel nel application.propertiesfile.

server.error.whitelabel.enabled=false

Questo dovrebbe funzionare anche per xmlrichieste / risposte. Ma non l'ho provato. Ha fatto esattamente quello che cercavo da quando stavo creando un'API RESTful e volevo solo restituire JSON.


2

server.error.whitelabel.enabled = false

Includi la riga sopra nelle cartelle delle risorse application.properties

Altro errore Risoluzione dei problemi fare riferimento a http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page


Ho provato application.properties nella mia cartella di installazione che non ha fatto nulla. La cartella application.properties in / src / main / resources è ciò che suganya sudarsan stava tentando di trasmettere. Sembra essere una "lettura a caldo" anche in Eclipse.
Richard Bradley Smith,

1

Stavo cercando di chiamare un endpoint REST da un microservizio e stavo usando il metodo put del resttemplate .

Nel mio disegno eventuale errore si è verificato all'interno del REST endpoint deve restituire una risposta di errore JSON, che stava lavorando per alcune chiamate, ma non per questo mettere uno, è tornato il pagina di errore white label , invece.

Così ho fatto qualche indagine e l'ho scoperto;

Spring cerca di capire se il chiamante è una macchina, quindi restituisce una risposta JSON o se si tratta di un browser che restituisce la pagina di errore dell'etichetta bianca HTML.

Di conseguenza: la mia app client doveva dire all'endpoint REST che il chiamante è una macchina, non un browser, quindi l'app client doveva aggiungere esplicitamente " application / json " nell'intestazione ACCEPT per il metodo "put" del resttemplate Ho aggiunto questo all'intestazione e risolto il problema.

la mia chiamata all'endpoint:

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

per la chiamata precedente ho dovuto aggiungere l'intestazione param.

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

o ho provato a cambiare anche put to exchange, in questo caso, la chiamata di scambio ha aggiunto la stessa intestazione per me e risolto anche il problema ma non so perché :)

restTemplate.exchange(....)

0

Spring Boot di default ha una pagina di errore " whitelabel " che puoi vedere in un browser se riscontri un errore del server. La pagina di errore Whitelabel è una pagina di errore generico di avvio di primavera che viene visualizzata quando non viene trovata alcuna pagina di errore personalizzata.

Impostare "server.error.whitelabel.enabled = false" per passare alla pagina di errore predefinita


0

Ho avuto un problema simile Messaggio di errore WhiteLabel sulla mia SPA angolare ogni volta che ho fatto un aggiornamento.

La correzione consisteva nel creare un controller che implementasse ErrorController ma invece di restituire una stringa, dovevo restituire un oggetto ModelAndView che inoltra a /

@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;
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.