Boot Musim Semi Hapus Halaman Kesalahan Daftar Putih

156

Saya mencoba untuk menghapus halaman kesalahan label putih, jadi apa yang saya lakukan adalah membuat pemetaan pengontrol untuk "/ kesalahan",

@RestController
public class IndexController {

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

}

Tapi sekarang saya mendapatkan kesalahan ini.

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

Tidak tahu apakah saya melakukan kesalahan. Tolong saran.

EDIT:

Sudah ditambahkan error.whitelabel.enabled=false ke file application.properties, masih mendapatkan kesalahan yang sama

Yasitha Waduge
sumber
1
Lihatlah proyek ini github.com/paulc4/mvc-exceptions/blob/master/src/main/java/… , sepertinya mereka memiliki halaman kesalahan yang dipetakan di dalamnya.
Innot Kauker
Sudahkah Anda mencoba pengaturan spring.resources.add-mappings=false?
geoand
Terima kasih atas sarannya, Ya masih mengalami kesalahan yang sama
Yasitha Waduge
Apakah Anda hanya mencoba mengembalikan beberapa konten khusus saat /errorjalur dipanggil?
geoand

Jawaban:

240

Anda perlu mengubah kode Anda sebagai berikut:

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

Kode Anda tidak berfungsi, karena Spring Boot secara otomatis mendaftarkan BasicErrorControllersebagai Spring Bean ketika Anda belum menentukan implementasi ErrorController.

Untuk melihat fakta itu, navigasikan saja ke ErrorMvcAutoConfiguration.basicErrorController sini .

geoand
sumber
1
Berlari ke masalah yang sama ke yang sama, saya mencari dokumen Spring tetapi tidak menyebutkan BasicErrorController. Ini bekerja :)
Mike R
4
Saya harus melalui sumber untuk menemukan yang ini :-)
geoand
1
Terima kasih, bekerja dengan baik! Tindak lanjut kecil jika Anda dapat memberikan petunjuk apa pun: misalkan kita mendapatkan penangan kesalahan ini karena beberapa pengecualian dilemparkan ke dalam aplikasi kami (dan Spring secara implisit menetapkan kode respons ke 500 yang benar); adakah cara mudah untuk mendapatkan pengecualian itu di sini (untuk memasukkan beberapa detail dalam pesan kesalahan yang dikembalikan)?
Jonik
1
Senang Anda menemukannya bermanfaat! Meskipun saya belum mencobanya, saya cukup yakin Anda dapat menggunakan prinsip-prinsip yang ditemukan di Spring Boot's BasicErrorController(lihat github.com/spring-projects/spring-boot/blob/… ) untuk mencapai apa yang Anda inginkan
geoand
3
Hmm, ya, terima kasih lagi! Pada awalnya saya tidak yakin bagaimana cara mendapatkan ErrorAttributesobjek itu (berisi detail kesalahan), tetapi kemudian saya mencoba hanya @Memutakhirkannya, dan itu berhasil. Untuk apa saya pergi sekarang: gist.github.com/jonikarppinen/662c38fb57a23de61c8b
Jonik
44

Jika Anda menginginkan halaman respons "JSONish" yang lebih banyak, Anda dapat mencoba sesuatu seperti itu:

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);
  }
}
acohen
sumber
7
Di Spring-Boot v2 kelas ErrorController dan ErrorAttributes ada dalam paket org.springframework.boot.web.servlet.error dan selanjutnya metode tanda tangan ErrorAttributes # getErrorAttributes telah berubah, harap perhatikan ketergantungan pada Spring-Boot v1 dan mungkin berikan petunjuk untuk v2, Terima kasih.
chrisinmtown
1
Ubah: Peta pribadi <String, Object> getErrorAttributes (HttpServletRequest aRequest, boolean includeStackTrace) {RequestAttributes requestAttributes = new ServletRequestAttributes (aRequest); return errorAttributes.getErrorAttributes (requestAttributes, includeStackTrace); } Oleh: private Map <String, Object> getErrorAttributes (permintaan HttpServletRequest, boolean includeStackTrace) {WebRequest webRequest = ServletWebRequest baru (permintaan); kembalikan this.errorAttributes.getErrorAttributes (webRequest, includeStackTrace); }
Rija Ramampiandra
2
Versi terbaru dari SimpleErrorController.java yang mempertimbangkan komentar dari atas dapat ditemukan di sini> gist.github.com/oscarnevarezleal/…
Oscar Nevarez
38

Spring boot doc 'salah' (sejak itu diperbaiki):

Untuk mematikannya Anda dapat mengatur error.whitelabel.enabled = false

seharusnya

Untuk mematikannya Anda dapat mengatur server.error.whitelabel.enabled = false

Willome
sumber
Ini akan menonaktifkan White Label Error Page tetapi spring boot akan memetakan titik akhir /error. Untuk membebaskan /errorset titik akhir server.error.path=/error-springatau beberapa jalur alternatif.
notes-jj
32

Anda dapat menghapusnya sepenuhnya dengan menetapkan:

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

Namun, harap dicatat bahwa hal itu mungkin akan menyebabkan halaman daftar putih kontainer servlet muncul sebagai gantinya :)


EDIT: Cara lain untuk melakukan ini adalah melalui application.yaml. Masukkan nilai:

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

Dokumentasi

Untuk Spring Boot <2.0, kelasnya berada dalam paket org.springframework.boot.autoconfigure.web.

hoodieman
sumber
15

Pengguna di sini mengatakan bahwa Anda harus mengatur server.error.whitelabel.enableduntuk falsemenonaktifkan halaman kesalahan standar. Mungkin itu yang Anda inginkan?

Saya mengalami kesalahan yang sama setelah menambahkan / pemetaan kesalahan, omong-omong.

Innot Kauker
sumber
Ya, saya telah menetapkan error.whitelabel.enabled = false tetapi masih mendapatkan kesalahan yang sama setelah menambahkan / memetakan kesalahan
Yasitha Waduge
Ini akan menonaktifkan White Label Error Page tetapi spring boot akan memetakan titik akhir /error. Untuk membebaskan /errorset titik akhir server.error.path=/error-springatau beberapa jalur alternatif.
notes-jj
11

Dengan Spring Boot> 1.4.x Anda bisa melakukan ini:

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

tetapi kemudian dalam kasus pengecualian wadah servlet akan menampilkan halaman kesalahan sendiri.

db80
sumber
8

Ini tergantung pada versi booting musim semi Anda:

Ketika SpringBootVersion <= 1.2kemudian gunakanerror.whitelabel.enabled = false

Ketika SpringBootVersion > = 1.3lalu gunakanserver.error.whitelabel.enabled = false

sendon1982
sumber
6

Di Spring Boot 1.4.1 menggunakan tempache Template, menempatkan error.html di bawah folder templates akan cukup:

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

Variabel tambahan dapat diteruskan dengan membuat pencegat untuk /error

Ecmel Ercan
sumber
3

Berikut adalah metode alternatif yang sangat mirip dengan "cara lama" dalam menentukan pemetaan kesalahan di web.xml .

Cukup tambahkan ini ke konfigurasi Spring Boot Anda:

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

}

Kemudian Anda dapat menentukan halaman kesalahan dalam konten statis secara normal.

Penyesuai juga bisa terpisah @Component, jika diinginkan.

rustyx
sumber
3

Saya menggunakan Spring Boot versi 2.1.2 dan errorAttributes.getErrorAttributes()tanda tangan tidak bekerja untuk saya (sebagai tanggapan acohen). Saya ingin respons tipe JSON jadi saya melakukan sedikit penggalian dan menemukan metode ini melakukan persis apa yang saya butuhkan.

Saya mendapatkan sebagian besar informasi saya dari utas ini serta dari posting blog ini .

Pertama, saya membuat CustomErrorControllerSpring yang akan mencari untuk memetakan kesalahan.

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

Kedua, saya membuat CustomHttpErrorResponsekelas untuk mengembalikan kesalahan sebagai 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
}

Akhirnya, saya harus mematikan Whitelabel dalam application.propertiesfile.

server.error.whitelabel.enabled=false

Ini bahkan harus bekerja untuk xmlpermintaan / tanggapan. Tapi saya belum mengujinya. Itu melakukan persis apa yang saya cari sejak saya membuat API tenang dan hanya ingin mengembalikan JSON.

Rumah DJ
sumber
2

server.error.whitelabel.enabled = false

Sertakan baris di atas ke folder Resources folder application.properties

Lebih Banyak Masalah Kesalahan diselesaikan silakan merujuk http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

suganya sudarsan
sumber
Saya mencoba application.properties di folder instalasi saya yang tidak melakukan apa-apa. Folder application.properties di bawah / src / main / resources adalah apa yang hendak disampaikan oleh suganya sudarsan. Tampaknya menjadi "hot read" di Eclipse juga.
Richard Bradley Smith
1

Saya mencoba memanggil titik akhir REST dari microservice dan saya menggunakan metode put resttemplate .

Dalam desain saya jika ada kesalahan terjadi di dalam titik akhir REST itu harus mengembalikan respons kesalahan JSON, itu berfungsi untuk beberapa panggilan tetapi tidak untuk put ini , ia mengembalikan halaman kesalahan label putih sebagai gantinya.

Jadi saya melakukan investigasi dan saya menemukan itu;

Spring mencoba untuk memahami penelepon jika itu adalah mesin maka ia mengembalikan respons JSON atau jika itu adalah browser daripada mengembalikan halaman kesalahan label putih HTML.

Akibatnya: aplikasi klien saya perlu mengatakan kepada REST titik akhir bahwa pemanggil adalah mesin, bukan browser sehingga untuk ini aplikasi klien perlu menambahkan ' aplikasi / json ' ke dalam header ACCEPT secara eksplisit untuk metode 'put' resttemplate. Saya menambahkan ini ke header dan memecahkan masalah.

panggilan saya ke titik akhir:

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

untuk panggilan di atas saya harus menambahkan param header di bawah ini.

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

atau saya mencoba mengubah put to exchange juga, dalam hal ini, panggilan pertukaran menambahkan header yang sama untuk saya dan menyelesaikan masalah juga, tetapi saya tidak tahu mengapa :)

restTemplate.exchange(....)
cazador
sumber
0

Spring Boot secara default memiliki halaman kesalahan " whitelabel " yang dapat Anda lihat di browser jika Anda menemukan kesalahan server. Whitelabel Error Page adalah halaman kesalahan Spring Boot generik yang ditampilkan ketika tidak ada halaman kesalahan khusus ditemukan.

Set "server.error.whitelabel.enabled = false" untuk beralih dari halaman kesalahan default

shatakshi
sumber
0

Saya memiliki masalah yang sama dengan pesan WhiteLabel Error pada Angular SPA saya setiap kali saya melakukan penyegaran.

Cara mengatasinya adalah membuat pengontrol yang mengimplementasikan ErrorController tetapi alih-alih mengembalikan sebuah String, saya harus mengembalikan objek ModelAndView yang meneruskan ke /

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