Spring Boot ลบหน้าข้อผิดพลาด Whitelabel


156

ฉันกำลังพยายามลบหน้าข้อผิดพลาดของ white label ดังนั้นสิ่งที่ฉันทำไปแล้วคือสร้างการแมปคอนโทรลเลอร์สำหรับ "/ error"

@RestController
public class IndexController {

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

}

แต่ตอนนี้ฉันได้รับข้อผิดพลาดนี้

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

ไม่รู้ว่าฉันทำอะไรผิดหรือเปล่า โปรดให้คำแนะนำ.

แก้ไข:

เพิ่ม error.whitelabel.enabled=false ไปยังไฟล์ application.properties แล้วยังได้รับข้อผิดพลาดเดียวกัน


1
ดูโครงการนี้github.com/paulc4/mvc-exceptions/blob/master/src/main/java/ ......ดูเหมือนว่าพวกเขามีหน้าข้อผิดพลาดที่แมปใหม่
Innot Kauker

คุณลองตั้งค่าแล้วspring.resources.add-mappings=falseหรือยัง
geoand

ขอบคุณสำหรับคำแนะนำใช่ยังคงมีข้อผิดพลาดเดียวกัน
Yasitha Waduge

คุณแค่พยายามส่งคืนเนื้อหาที่กำหนดเองบางส่วนเมื่อ/errorมีการเรียกพา ธ
geoand

คำตอบ:


240

คุณต้องเปลี่ยนรหัสของคุณเป็นสิ่งต่อไปนี้:

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

รหัสของคุณไม่ทำงานเนื่องจาก Spring Boot ลงทะเบียนโดยอัตโนมัติBasicErrorControllerเป็น Spring Bean เมื่อคุณไม่ได้ระบุการใช้งานErrorControllerเมื่อคุณไม่ได้ระบุการดำเนินการของ

หากต้องการดูความจริงที่ว่าเพียงไปที่นี่ErrorMvcAutoConfiguration.basicErrorController


1
วิ่งเข้าไปในปัญหาเดียวกันฉันค้นหา Spring docs แต่ไม่ได้พูดถึง BasicErrorController ใช้งานได้ :)
Mike R

4
ฉันต้องผ่านแหล่งข้อมูลเพื่อค้นหาสิ่งนี้ :-)
geoand

1
ขอบคุณทำงานได้ดีมาก! การติดตามเล็กน้อยหากคุณสามารถให้พอยน์เตอร์ใด ๆ : บอกว่าเราได้รับตัวจัดการข้อผิดพลาดนี้เนื่องจากมีข้อผิดพลาดบางอย่างเกิดขึ้นในแอปของเรา (และสปริงตั้งรหัสตอบสนองเป็น 500 ซึ่งถูกต้อง) มีวิธีที่ง่ายต่อการได้รับการยกเว้นจากที่นี่ (เพื่อรวมรายละเอียดบางอย่างในการส่งคืนข้อผิดพลาด)?
Jonik

1
ดีใจที่คุณพบว่ามันมีประโยชน์! แม้ว่าฉันจะไม่ได้ลอง แต่ฉันค่อนข้างมั่นใจว่าคุณสามารถใช้หลักการที่พบใน Spring Boot's BasicErrorController(ดูgithub.com/spring-projects/spring-boot/blob/ ...... ) เพื่อบรรลุสิ่งที่คุณต้องการ
geoand

3
อืมใช่ขอบคุณอีกครั้ง! ตอนแรกฉันไม่แน่ใจว่าจะรับErrorAttributesวัตถุนั้นได้อย่างไร (มีรายละเอียดข้อผิดพลาด) แต่ฉันก็ลอง @Autowiring ง่ายๆแล้วก็ใช้งานได้ สิ่งที่ฉันไปด้วยในตอนนี้: gist.github.com/jonikarppinen/662c38fb57a23de61c8b
Jonik

44

หากคุณต้องการหน้าตอบสนอง "JSONish" เพิ่มเติมคุณสามารถลองทำสิ่งต่อไปนี้:

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 คลาส ErrorController และ ErrorAttributes อยู่ในแพ็คเกจ org.springframework.boot.web.servlet.error และลายเซ็นของเมธอด ErrorAttributes # getErrorAttributes เพิ่มเติมนั้นโปรดสังเกตการพึ่งพา Spring-Boot v1 และอาจให้คำแนะนำสำหรับ v2 ขอบคุณ.
chrisinmtown

1
เปลี่ยนแปลง: ไพรเวตแม็พ <String, Object> getErrorAttributes (HttpServletRequest aRequest, บูลีน includeStackTrace) {RequestAttributes RequestAttributes = new ServletRequestAttributes (aRequest); return errorAttributes.getErrorAttributes (requestAttributes, includeStackTrace); } โดย: แผนที่ส่วนตัว <String, Object> getErrorAttributes (คำขอ HttpServletRequest, บูลีน includeStackTrace) {WebRequest webRequest = ใหม่ ServletWebRequest (ขอ); กลับ this.errorAttributes.getErrorAttributes (webRequest, includeStackTrace); }
Rija Ramampiandra

2
เวอร์ชั่นล่าสุดของ SimpleErrorController.java พิจารณาความคิดเห็นจากด้านบนสามารถพบได้ที่นี่> gist.github.com/oscarnevarezleal/ …
Oscar Nevarez

38

Spring boot doc 'ผิด' (ตั้งแต่แก้ไขไปแล้ว):

หากต้องการปิดเครื่องคุณสามารถตั้งค่าerror.whitelabel.enabled = false

ควรจะเป็น

หากต้องการปิดเครื่องคุณสามารถตั้งค่าserver.error.whitelabel.enabled = false


นี่จะเป็นการปิดการใช้งาน White Label Error Page แต่การบูทสปริงจะแมปจุดสิ้นสุด/errorอยู่แล้ว ในการทำให้ฟรี/errorชุดปลายทางserver.error.path=/error-springหรือเส้นทางอื่น
notes-jj

32

คุณสามารถลบออกได้อย่างสมบูรณ์โดยการระบุ:

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

อย่างไรก็ตามอย่าลืมว่าการทำเช่นนั้นอาจจะทำให้หน้าเว็บที่มีป้ายกำกับ White ของ Container แสดงขึ้นมาแทน :)


แก้ไข: อีกวิธีหนึ่งในการทำเช่นนี้คือผ่าน application.yaml เพียงแค่ใส่ค่า:

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

เอกสาร

สำหรับฤดูใบไม้ผลิ Boot <2.0 org.springframework.boot.autoconfigure.webชั้นตั้งอยู่ในแพคเกจ


15

คู่มือการใช้งานที่นี่บอกว่าคุณต้องตั้งserver.error.whitelabel.enabledไปfalseปิดการใช้งานหน้าข้อผิดพลาดมาตรฐาน บางทีมันเป็นสิ่งที่คุณต้องการ?

ฉันพบข้อผิดพลาดเดียวกันหลังจากเพิ่ม / แมปผิดพลาดตามวิธี


ใช่ฉันได้ตั้งค่า error.whitelabel.enabled = false แล้ว แต่ยังคงได้รับข้อผิดพลาดเดิมหลังจากเพิ่ม / การจับคู่ข้อผิดพลาด
Yasitha Waduge

นี่จะเป็นการปิดการใช้งาน White Label Error Page แต่การบูทสปริงจะแมปจุดสิ้นสุด/errorอยู่แล้ว ในการทำให้ฟรี/errorชุดปลายทางserver.error.path=/error-springหรือเส้นทางอื่น
notes-jj

11

ด้วย Spring Boot> 1.4.x คุณสามารถทำได้:

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

แต่ในกรณีที่มีข้อยกเว้นภาชนะ servlet จะแสดงหน้าข้อผิดพลาดของตัวเอง



6

ใน Spring Boot 1.4.1 ใช้เทมเพลต Mustache การวาง error.html ภายใต้โฟลเดอร์ templates จะเพียงพอ:

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

ตัวแปรเพิ่มเติมสามารถส่งผ่านได้โดยสร้าง interceptor สำหรับ /error



3

ต่อไปนี้เป็นวิธีทางเลือกซึ่งคล้ายกับ "วิธีแบบเก่า" ในการระบุการแมปข้อผิดพลาด web.xmlของการระบุผิดพลาดในการแมป

เพียงเพิ่มสิ่งนี้ลงในการกำหนดค่า 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"));
    }

}

จากนั้นคุณสามารถกำหนดหน้าข้อผิดพลาดในเนื้อหาคงที่ตามปกติ

Customizer สามารถแยก@Componentได้ถ้าต้องการ


3

ฉันใช้ Spring Boot เวอร์ชัน 2.1.2 และ errorAttributes.getErrorAttributes()ลายเซ็นไม่ทำงานสำหรับฉัน (ในการตอบสนองของ acohen) ฉันต้องการคำตอบประเภท JSON ดังนั้นฉันจึงขุดเล็กน้อยและพบว่าวิธีนี้ทำในสิ่งที่ฉันต้องการ

ฉันได้รับข้อมูลส่วนใหญ่จากหัวข้อนี้รวมถึงโพสต์บล็อกนี้นี้

ก่อนอื่นฉันสร้างCustomErrorControllerSpring ขึ้นมาเพื่อหาข้อผิดพลาด

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

ประการที่สองฉันสร้างCustomHttpErrorResponseคลาสเพื่อส่งคืนข้อผิดพลาดเป็น 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
}

ในที่สุดฉันต้องปิด Whitelabel ในapplication.propertiesไฟล์

server.error.whitelabel.enabled=false

สิ่งนี้ควรใช้กับxmlคำขอ / คำตอบด้วย แต่ฉันยังไม่ได้ทดสอบ มันทำสิ่งที่ฉันกำลังมองหาตั้งแต่ฉันสร้าง RESTful API และต้องการส่งคืน JSON เท่านั้น


2

server.error.whitelabel.enabled = false

รวมบรรทัดข้างต้นลงในโฟลเดอร์ทรัพยากร application.properties

การแก้ไขปัญหาข้อผิดพลาดเพิ่มเติมโปรดอ้างอิงhttp://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page


ฉันลอง application.properties ในโฟลเดอร์การติดตั้งซึ่งไม่ได้ทำอะไรเลย โฟลเดอร์ application.properties ภายใต้ / src / main / resources คือสิ่งที่ suganya sudarsan พยายามถ่ายทอด ดูเหมือนว่าจะเป็น "hot read" ใน Eclipse เช่นกัน
Richard Bradley Smith

1

ฉันพยายามโทรหา REST endpoint จาก microservice และฉันใช้วิธีวางของ resttemplate

ในการออกแบบของฉันหากข้อผิดพลาดใด ๆ ที่เกิดขึ้นภายในปลายทาง REST มันควรกลับมาตอบสนองข้อผิดพลาด JSON มันก็ทำงานได้สำหรับการโทรบางส่วน แต่ไม่ได้สำหรับการวางนี้มันกลับหน้าข้อผิดพลาดฉลากสีขาวแทน

ดังนั้นฉันจึงทำการตรวจสอบและพบว่า;

Spring พยายามเข้าใจผู้โทรหากเป็นเครื่องจากนั้นจะส่งคืนการตอบสนอง JSON หรือเป็นเบราว์เซอร์มากกว่าที่จะส่งกลับหน้าข้อผิดพลาด White label HTML

ผลที่ตามมา: แอปลูกค้าของฉันจำเป็นต้องพูดกับปลายทาง REST ว่าผู้เรียกเป็นเครื่องไม่ใช่เบราว์เซอร์ดังนั้นสำหรับแอปพลิเคชันไคลเอนต์ที่จำเป็นในการเพิ่ม ' application / json ' ลงในส่วนหัว ACCEPT อย่างชัดเจนสำหรับวิธีการ 'วาง' ของ resttemplate ฉันเพิ่มสิ่งนี้ในส่วนหัวและแก้ไขปัญหา

การโทรถึงจุดสิ้นสุด:

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

สำหรับการโทรด้านบนฉันต้องเพิ่มพารามิเตอร์ส่วนหัวด้านล่าง

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

หรือฉันพยายามเปลี่ยน put to exchange เช่นกันในกรณีนี้ exchange call เพิ่มส่วนหัวเดียวกันสำหรับฉันและแก้ไขปัญหาด้วย แต่ฉันไม่รู้ว่าทำไม :)

restTemplate.exchange(....)

0

Spring Boot โดยค่าเริ่มต้นจะมี“ whitelabelหน้าข้อผิดพลาด“ ” ซึ่งคุณสามารถเห็นได้ในเบราว์เซอร์หากคุณพบข้อผิดพลาดของเซิร์ฟเวอร์ Whitelabel Error Page เป็นหน้าข้อผิดพลาด Spring Boot ทั่วไปซึ่งจะปรากฏขึ้นเมื่อไม่พบหน้าข้อผิดพลาดที่กำหนดเอง

ตั้ง“ server.error.whitelabel.enabled = false” เพื่อเปลี่ยนหน้าข้อผิดพลาดเริ่มต้น


0

ฉันมีปัญหาคล้ายกัน WhiteLabel Error message ใน Angular SPA ทุกครั้งที่รีเฟรช

การแก้ไขคือการสร้างตัวควบคุมที่ใช้ ErrorController แต่แทนที่จะส่งคืนสตริงฉันต้องส่งคืนวัตถุ ModelAndView ที่ส่งต่อไปยัง/

@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;
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.