Spring Boot Whitelabel Hata Sayfasını Kaldır


157

Beyaz etiket hata sayfasını kaldırmaya çalışıyorum, bu yüzden yaptığım "/ error" için bir denetleyici eşlemesi oluşturuldu,

@RestController
public class IndexController {

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

}

Ama şimdi bu hatayı alıyorum.

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

Yanlış bir şey yapıp yapmadığımı bilmiyorum. Lütfen tavsiye.

DÜZENLE:

error.whitelabel.enabled=false Application.properties dosyasına zaten eklenmiş , yine de aynı hatayı alıyor


1
Bu projeye bakın github.com/paulc4/mvc-exceptions/blob/master/src/main/java/… , içinde hata sayfası yeniden eşleme var gibi görünüyor.
Innot Kauker

Ayarlamayı denediniz spring.resources.add-mappings=falsemi?
geoand

Öneri için teşekkürler, Evet hala aynı hatayı aldı
Yasitha Waduge

Sadece /erroryol çağrıldığında bazı özel içerikler döndürmeye mi çalışıyorsunuz ?
geoand

Yanıtlar:


241

Kodunuzu aşağıdaki şekilde değiştirmeniz gerekir:

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

Kodunuz çalışmadı, çünkü Spring Boot BasicErrorControllerbir uygulamasını belirtmediğinizde otomatik olarak bir Spring Bean olarak kaydeder ErrorController.

Bu gerçeği görmek için ErrorMvcAutoConfiguration.basicErrorController buraya gidin .


1
Aynı meseleye koştum, Bahar belgelerini aradım ama BasicErrorController'dan bahsetmedi. Bu çalışıyor :)
Mike R

4
Bunu bulmak için kaynak geçmesi gerekiyordu :-)
geoand 4

1
Teşekkürler, güzel çalıştı! Eğer herhangi bir işaretçi verebilir küçük bir takip: bizim app bazı istisna atıldı çünkü bu hata işleyicisi olsun diyelim (ve Bahar dolaylı olarak doğru yanıt kodu 500 ayarlar); burada bu istisnayı ele almanın kolay bir yolu var mı (döndürülen hata mesajına bazı detayları dahil etmek için)?
Jonik

1
Bunu yararlı bulduğunuz için memnunuz! Denememiş olmama rağmen, istediğinizi gerçekleştirmek için Spring Boot'unBasicErrorController (bkz. Github.com/spring-projects/spring-boot/blob/… ) prensiplerini kullanabileceğinizden eminim
geoand

3
Hmm, evet, tekrar teşekkürler! İlk başta ErrorAttributes(hata ayrıntılarını içeren) bu nesneyi nasıl alacağımdan emin değildim , ama sonra sadece @Outowiring'i denedim ve işe yarıyor. Şimdilik neler yaptım: gist.github.com/jonikarppinen/662c38fb57a23de61c8b
Jonik

44

Daha "JSONish" yanıt sayfası istiyorsanız, bunun gibi bir şey deneyebilirsiniz:

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
Spring-Boot v2'de ErrorController ve ErrorAttributes sınıfları org.springframework.boot.web.servlet.error paketinde bulunmaktadır ve daha sonra ErrorAttributes # getErrorAttributes yöntem imzası değişmiştir, lütfen Spring-Boot v1'e bağımlılığı not edin ve muhtemelen v2 için ipuçları verin, Teşekkürler.
chrisinmtown

1
Değiştir: özel harita <dize, nesne> getErrorAttributes (HttpServletRequest aRequest, bool include includeStackTrace) {RequestAttributes requestAttributes = yeni ServletRequestAttributes (aRequest); return errorAttributes.getErrorAttributes (requestAttributes, includeStackTrace); } Gönderen: private Map <String, Object> getErrorAttributes (HttpServletRequest isteği, boolean includeStackTrace) {WebRequest webRequest = new ServletWebRequest (istek); return this.errorAttributes.getErrorAttributes (webRequest, includeStackTrace); }
Rija Ramampiandra

2
Yukarıdaki yorumları dikkate alarak SimpleErrorController.java'nın güncellenmiş bir sürümünü burada bulabilirsiniz> gist.github.com/oscarnevarezleal/…
Oscar Nevarez

38

Spring boot doc 'was' (o zamandan beri düzelttiler):

Kapatmak için error.whitelabel.enabled = false olarak ayarlayabilirsiniz.

olmalı

Kapatmak için server.error.whitelabel.enabled = false olarak ayarlayabilirsiniz.


Bu, Beyaz Etiket Hata Sayfasını devre dışı bırakır, ancak bahar önyükleme /erroryine de uç noktayı eşler. Uç nokta /errorkümesini server.error.path=/error-springveya alternatif bir yolu serbest bırakmak için .
notes-jj

32

Şunları belirterek tamamen kaldırabilirsiniz:

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

Ancak, bunu yapmanın büyük olasılıkla sunucu uygulaması kabının beyaz etiket sayfalarının görünmesine neden olacağını unutmayın :)


EDIT: Bunu yapmanın başka bir yolu application.yaml. Sadece değeri girin:

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

belgeleme

Spring Boot <2.0 için sınıf pakette bulunur org.springframework.boot.autoconfigure.web.


15

Manuel burada sen setine sahip olduklarını söyledi server.error.whitelabel.enablediçinfalse , standart hata sayfasını devre dışı bırakmak . Belki ne istiyorsun?

Bu arada / hata eşlemesi ekledikten sonra aynı hatayı yaşıyorum.


Evet zaten error.whitelabel.enabled = false ama hala ekleme / hata haritalama sonrasında aynı hatayı alıyorum kurdum
Yasitha Waduge

Bu, Beyaz Etiket Hata Sayfasını devre dışı bırakır, ancak bahar önyükleme /erroryine de uç noktayı eşler. Uç nokta /errorkümesini server.error.path=/error-springveya alternatif bir yolu serbest bırakmak için .
notes-jj

11

Spring Boot> 1.4.x ile bunu yapabilirsiniz:

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

ancak istisna olması durumunda sunucu uygulaması kapsayıcısı kendi hata sayfasını görüntüler.



6

Bıyık şablonları kullanan Spring Boot 1.4.1'de error.html'yi şablonlar klasörünün altına yerleştirmek yeterli olacaktır:

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

Ek değişkenler, /error



4

Spring Boot sürüm 2.1.2 kullanıyorum ve errorAttributes.getErrorAttributes()imza benim için işe yaramadı (acohen'ın cevabında). Biraz kazma yaptı ve bu yöntemi tam olarak ne gerekli olduğunu buldum bir JSON türü yanıt istedim.

Bilgilerimin çoğunu bu yazının yanı sıra bu blog gönderisinden aldım .

İlk olarak, CustomErrorControllerSpring'in herhangi bir hatayı eşlemek için arayacağı bir tane oluşturdum .

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

İkinci olarak, CustomHttpErrorResponsehatayı JSON olarak döndürmek için bir sınıf oluşturdum .

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
}

Sonunda, dosyadaki Whitelabel'i kapatmak zorunda kaldım application.properties.

server.error.whitelabel.enabled=false

Bu, xmlistek / yanıtlar için bile çalışmalıdır . Ama bunu test etmedim. RESTful API oluşturma ve sadece JSON dönmek istedim beri tam olarak ne aradığını yaptı.


3

Burada, hata eşlemelerini belirtmenin "eski yöntemine" çok benzeyen alternatif bir yöntem var. web.xml .

Bunu Spring Boot yapılandırmanıza ekleyin:

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

}

Ardından statik içerikteki hata sayfalarını normal olarak tanımlayabilirsiniz.

Özelleştirici ayrıca istenirse ayrı bir olabilir @Component.


2

server.error.whitelabel.enabled = kapalı

Yukarıdaki satırı Kaynak klasörleri uygulamasına ekleyin.

Daha fazla Hata Sorunu çözmek için lütfen http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page adresini ziyaret edin.


Hiçbir şey yapmayan kurulum klasörümde application.properties komutunu denedim. / Src / main / resources altındaki application.properties klasörü, suganya sudarsan'ın iletmeye çalıştığı şeydir. Eclipse'de de "sıcak okuma" gibi görünüyor.
Richard Bradley Smith

1

Bir mikro hizmetten bir REST bitiş noktası çağırmak çalışıyordum ve resttemplate'ın put yöntemini kullanıyordum.

Tasarımımda REST uç noktası içinde herhangi bir hata meydana geldiğinde bir JSON hata yanıtı döndürmelidir, bazı çağrılar için çalışıyordu, ancak bu koymak için değil , bunun yerine beyaz etiket hata sayfasını döndürdü .

Bu yüzden biraz araştırma yaptım ve öğrendim;

Bahar bir makine ise aramayı anlamaya çalışın, sonra JSON yanıtı döndürür veya beyaz etiket hata sayfası HTML'sini döndürdüğünden daha bir tarayıcıysa .

Sonuç olarak: istemci uygulamamın REST son noktasına, arayanın bir tarayıcı değil bir makine olduğunu söylemesi gerekiyordu, bu nedenle istemci uygulaması , resttemplate'in 'put' yöntemi için açıkça ACCEPT başlığına ' application / json ' eklemesi gerekiyordu . Bunu başlığa ekledim ve sorunu çözdüm.

uç noktaya yaptığım çağrı:

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

yukarıdaki çağrı için başlığı param altına eklemek zorunda kaldı.

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

ya da ben de takas değiştirmeyi denedim, bu durumda, değişim çağrısı benim için aynı başlığı ekledi ve sorunu da çözdüm ama neden bilmiyorum :)

restTemplate.exchange(....)

1

Ne zaman bir yenileme yaptığımda Angular SPA benim benzer bir sorun WhiteLabel Hata mesajı vardı.

Düzeltme ErrorController uygulayan bir denetleyici oluşturmak oldu, ancak bir String döndürmek yerine, /

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

0

Spring Boot varsayılan olarak bir sunucu hatasıyla karşılaşırsanız tarayıcıda görebileceğiniz bir " whitelabel " hata sayfasına sahiptir. Beyaz Etiket Hata Sayfası, özel bir hata sayfası bulunmadığında görüntülenen genel bir Bahar Önyükleme hata sayfasıdır.

Varsayılan hata sayfasını değiştirmek için “server.error.whitelabel.enabled = false” olarak ayarlayın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.