Spring Boot Xóa trang lỗi Whitelabel


155

Tôi đang cố xóa trang lỗi nhãn trắng, vì vậy những gì tôi đã làm được tạo ra ánh xạ bộ điều khiển cho "/ error",

@RestController
public class IndexController {

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

}

Nhưng bây giờ tôi đang nhận được lỗi này.

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

Không biết liệu tôi có làm gì sai không. Vui lòng cho lời khuyên.

BIÊN TẬP:

Đã được thêm vào error.whitelabel.enabled=false tệp application.properIES, vẫn nhận được cùng một lỗi


1
Nhìn vào dự án này github.com/paulc4/mvc-exceptions/blob/master/src/main/java/ chủ , dường như họ có lỗi ánh xạ trang trong đó.
Innot Kauker

Bạn đã thử cài đặt spring.resources.add-mappings=falsechưa?
Geoand

Cảm ơn lời đề nghị, Có vẫn nhận được lỗi tương tự
Yasitha Waduge

Bạn chỉ đang cố gắng trả lại một số nội dung tùy chỉnh khi /errorđường dẫn được gọi?
Geoand

Câu trả lời:


239

Bạn cần thay đổi mã của bạn thành như sau:

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

Mã của bạn không hoạt động, vì Spring Boot tự động đăng ký BasicErrorControllerdưới dạng Spring Bean khi bạn chưa chỉ định triển khai ErrorController.

Để thấy thực tế đó chỉ cần điều hướng đến ErrorMvcAutoConfiguration.basicErrorController đây .


1
Gặp vấn đề tương tự, tôi đã tìm kiếm các tài liệu Spring nhưng nó không đề cập đến BasicErrorControll. Điều này hoạt động :)
Mike R

4
Tôi đã phải đi qua nguồn để tìm cái này :-)
Geoand

1
Cảm ơn, làm việc tốt! Một theo dõi nhỏ nếu bạn có thể đưa ra bất kỳ gợi ý nào: giả sử chúng tôi gặp phải trong trình xử lý lỗi này vì một số ngoại lệ đã bị ném trong ứng dụng của chúng tôi (và Spring ngầm đặt mã phản hồi thành 500 là chính xác); Có cách nào dễ dàng để giữ ngoại lệ đó ở đây không (để bao gồm một số chi tiết trong thông báo lỗi được trả về)?
Jonik

1
Thật vui khi bạn thấy nó hữu ích! Mặc dù tôi chưa thử nhưng tôi khá chắc chắn rằng bạn có thể sử dụng các nguyên tắc được tìm thấy trong Spring Boot BasicErrorController(xem github.com/spring-projects/spring-boot/blob/ .) Để thực hiện những gì bạn muốn
Geoand 20/2

3
Hmm, vâng, cảm ơn một lần nữa! Lúc đầu, tôi không chắc chắn làm thế nào để có được ErrorAttributesđối tượng đó (có chứa các chi tiết lỗi), nhưng sau đó tôi đã thử đơn giản @Autowires nó và nó hoạt động. Những gì tôi đã đi với bây giờ: gist.github.com/jonikarppinen/662c38fb57a23de61c8b
Jonik

44

Nếu bạn muốn có một trang phản hồi "JSONish" hơn, bạn có thể thử một cái gì đó như thế:

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
Trong Spring-Boot v2, các lớp ErrorContoder và ErrorAttribution nằm trong gói org.springframework.boot.web.servlet.error và hơn nữa chữ ký phương thức ErrorAttribution # getErrorAttribution đã thay đổi, vui lòng lưu ý sự phụ thuộc vào Spring-Boot v1 và có thể đưa ra gợi ý cho v2, cám ơn.
chrisinmtown

1
Thay đổi: Bản đồ riêng <String, Object> getErrorAttribut (HttpServletRequest aRequest, boolean includeStackTrace) {RequestAttribut requestAttribut = new ServletRequestAttribut (aRequest); return errorAttribut.getErrorAttribut (requestAttribut, includeStackTrace); } Bởi: Bản đồ riêng <String, Object> getErrorAttribut (yêu cầu httpServletRequest, boolean gồmStackTrace) {WebRequest webRequest = new ServletWebRequest (request); return this.errorAttribut.getErrorAttribut (webRequest, includeStackTrace); }
Rija Ramampiandra

2
Có thể tìm thấy phiên bản cập nhật của SimpleErrorControll.java khi xem xét các nhận xét từ phía trên tại đây> gist.github.com/oscarnevarezleal/ trộm
Oscar Nevarez

38

Spring boot doc 'đã' sai (họ đã sửa nó):

Để tắt nó, bạn có thể đặt error.whitelabel.enables = false

nên là

Để tắt nó, bạn có thể đặt server.error.whitelabel.enables = false


Điều này sẽ vô hiệu hóa Trang Lỗi Nhãn Trắng nhưng mùa xuân khởi động sẽ ánh xạ điểm cuối /error. Để giải phóng các thiết bị đầu cuối /errorbộ server.error.path=/error-springhoặc một số con đường thay thế.
ghi chú-jj

32

Bạn có thể loại bỏ nó hoàn toàn bằng cách chỉ định:

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

Tuy nhiên, xin lưu ý rằng làm như vậy có thể sẽ khiến các trang danh sách trắng của servlet hiển thị thay thế :)


EDIT: Một cách khác để làm điều này là thông qua application.yaml. Chỉ cần đặt giá trị:

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

Tài liệu

Đối với Spring Boot <2.0, lớp được đặt trong gói org.springframework.boot.autoconfigure.web.


15

Hướng dẫn sử dụng ở đây nói rằng bạn phải thiết lập server.error.whitelabel.enabledđể falsevô hiệu hóa các trang lỗi chuẩn. Có lẽ đó là những gì bạn muốn?

Nhân tiện, tôi đang gặp lỗi tương tự sau khi thêm / ánh xạ lỗi.


Có, tôi đã đặt lỗi.whlistabel.enables = false nhưng vẫn gặp lỗi tương tự sau khi thêm / ánh xạ lỗi
Yasitha Waduge

Điều này sẽ vô hiệu hóa Trang Lỗi Nhãn Trắng nhưng mùa xuân khởi động sẽ ánh xạ điểm cuối /error. Để giải phóng các thiết bị đầu cuối /errorbộ server.error.path=/error-springhoặc một số con đường thay thế.
ghi chú-jj

11

Với Spring Boot> 1.4.x bạn có thể làm điều này:

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

nhưng trong trường hợp ngoại lệ, thùng chứa servlet sẽ hiển thị trang lỗi của chính nó.


8

Điều này phụ thuộc vào phiên bản khởi động mùa xuân của bạn:

Khi SpringBootVersion <= 1.2thì sử dụngerror.whitelabel.enabled = false

Khi SpringBootVersion > = 1.3thì sử dụngserver.error.whitelabel.enabled = false


6

Trong Spring Boot 1.4.1 bằng cách sử dụng các mẫu Mustache, đặt error.html trong thư mục mẫu sẽ là đủ:

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

Các biến bổ sung có thể được thông qua bằng cách tạo một bộ chặn cho /error



3

Đây là một phương pháp thay thế rất giống với "cách cũ" trong việc chỉ định ánh xạ lỗi trong web.xml.

Chỉ cần thêm nó vào cấu hình Spring Boot của bạn:

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

}

Sau đó, bạn có thể xác định các trang lỗi trong nội dung tĩnh bình thường.

Tùy biến cũng có thể là một riêng biệt @Component, nếu muốn.


3

Tôi đang sử dụng Spring Boot phiên bản 2.1.2 và errorAttributes.getErrorAttributes() chữ ký không hoạt động với tôi (theo phản hồi của acohen). Tôi muốn có một phản hồi kiểu JSON vì vậy tôi đã đào một ít và thấy phương thức này đã làm chính xác những gì tôi cần.

Tôi đã nhận được hầu hết thông tin của tôi từ chủ đề này cũng như bài đăng trên blog này .

Đầu tiên, tôi đã tạo một CustomErrorControllerSpring mà sẽ tìm để ánh xạ bất kỳ lỗi nào.

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

Thứ hai, tôi đã tạo một CustomHttpErrorResponselớp để trả về lỗi dưới dạng 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
}

Cuối cùng, tôi phải tắt Whitelabel trong application.propertiestập tin.

server.error.whitelabel.enabled=false

Điều này thậm chí sẽ làm việc cho xmlcác yêu cầu / phản hồi. Nhưng tôi đã không kiểm tra điều đó. Nó đã làm chính xác những gì tôi đang tìm kiếm vì tôi đang tạo API RESTful và chỉ muốn trả về JSON.


2

server.error.whitelabel.enables = false

Bao gồm dòng trên cho ứng dụng thư mục Tài nguyên ứng dụng.

Giải quyết thêm vấn đề về lỗi, vui lòng tham khảo http://docs.spring.io/spring-boot/docs/civerse/reference/htmlsingle/#howto-customize-the-whitelabel-error-page


Tôi đã thử application.properations trong thư mục cài đặt của mình mà không làm gì cả. Thư mục application.properIES dưới / src / main / resource là những gì suganya sudarsan đang cố gắng truyền đạt. Nó dường như cũng là một "đọc nóng" trong Eclipse.
Richard Bradley Smith

1

Tôi đã cố gắng gọi điểm cuối REST từ microservice và tôi đang sử dụng phương thức đặt của resttemplate .

Trong thiết kế của tôi nếu có lỗi xảy ra bên trong REST Endpoint nó phải trả lại một phản ứng lỗi JSON, nó đã làm việc cho một số cuộc gọi nhưng không cho điều này đặt một, nó trả lại trang lỗi nhãn trắng để thay thế.

Vì vậy, tôi đã làm một số điều tra và tôi phát hiện ra rằng;

Spring cố gắng hiểu người gọi nếu đó là máy thì nó trả về phản hồi JSON hoặc nếu đó là trình duyệt thì nó trả về trang lỗi nhãn trắng HTML .

Kết quả là: ứng dụng khách của tôi cần nói với điểm cuối REST rằng người gọi là máy chứ không phải trình duyệt, vì vậy, ứng dụng khách này cần thêm ' application / json ' vào tiêu đề ACCEPT một cách rõ ràng cho phương thức 'đặt' của resttemplate. Tôi đã thêm điều này vào tiêu đề và giải quyết vấn đề.

cuộc gọi của tôi đến điểm cuối:

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

cho cuộc gọi ở trên, tôi đã phải thêm vào dưới tiêu đề param.

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

hoặc tôi cũng đã cố gắng thay đổi để trao đổi, trong trường hợp này, cuộc gọi trao đổi đã thêm tiêu đề tương tự cho tôi và cũng giải quyết vấn đề nhưng tôi không biết tại sao :)

restTemplate.exchange(....)

0

Spring Boot theo mặc định có một danh sách trắng trang lỗi danh sách mà bạn có thể thấy trong trình duyệt nếu bạn gặp lỗi máy chủ. Trang lỗi Whitelabel là trang lỗi Spring Boot chung được hiển thị khi không tìm thấy trang lỗi tùy chỉnh.

Đặt server server.error.whitelabel.enables = false Để chuyển trang lỗi mặc định


0

Tôi gặp vấn đề tương tự Thông báo lỗi WhiteLabel trên Angular SPA của tôi mỗi khi tôi làm mới.

Cách khắc phục là tạo một bộ điều khiển thực hiện ErrorContoder nhưng thay vì trả về Chuỗi, tôi phải trả về một đối tượng ModelAndView chuyển tiếp tới /

@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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.