Spring Boot删除Whitelabel错误页面

时间:2014-08-18 05:21:29

标签: spring spring-boot

我试图删除白标错误页面,所以我已经完成了为" /错误",

创建的控制器映射
@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文件,仍然得到相同的错误

14 个答案:

答案 0 :(得分:218)

您需要将代码更改为以下内容:

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

您的代码无效,因为当您未指定BasicErrorController的实现时,Spring Boot会自动将ErrorController注册为Spring Bean。

要查看该事实,只需导航至ErrorMvcAutoConfiguration.basicErrorController here

答案 1 :(得分:41)

如果你想要一个更“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);
  }
}

答案 2 :(得分:33)

Spring boot doc'错了(他们已经修好了):

  

要关闭它,您可以设置 error.whitelabel.enabled = false

应该是

  

要关闭它,您可以设置 server.error.whitelabel.enabled = false

答案 3 :(得分:30)

您可以通过指定:

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

但是,请注意这样做可能会导致servlet容器的白标签页面出现:)


编辑:另一种方法是通过application.yaml。只需输入值:

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

Documentation

对于Spring Boot&lt; 2.0,该类位于包org.springframework.boot.autoconfigure.web

答案 4 :(得分:15)

手动here表示您必须将server.error.whitelabel.enabled设置为false才能停用标准错误页面。也许这就是你想要的?

顺便提一句,我在添加/错误映射后遇到了同样的错误。

答案 5 :(得分:11)

使用Spring Boot&gt; 1.4.x你可以这样做:

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

但是如果异常,servlet容器将显示自己的错误页面。

答案 6 :(得分:6)

这取决于您的春季启动版本:

SpringBootVersion&lt; = 1.2时,请使用error.whitelabel.enabled = false

SpringBootVersion&gt; = 1.3时,请使用server.error.whitelabel.enabled = false

答案 7 :(得分:5)

在使用Mustache模板的Spring Boot 1.4.1中,将errors.html放在模板文件夹下就足够了:

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

可以通过为/error

创建拦截器来传递其他变量

答案 8 :(得分:2)

这是另一种方法,与在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"));
    }

}

然后,您可以正常地在静态内容中定义错误页面。

如果需要,定制器也可以是单独的@Component

答案 9 :(得分:1)

server.error.whitelabel.enabled =假

将上述行包含在Resources文件夹application.properties

更多错误问题解决请参阅http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

答案 10 :(得分:1)

默认情况下,Spring Boot具有一个“ whitelabel”错误页面,如果遇到服务器错误,您可以在浏览器中看到该页面。 Whitelabel错误页面是通用的Spring Boot错误页面,当找不到自定义错误页面时显示。

设置“ server.error.whitelabel.enabled = false”以切换默认错误页面

答案 11 :(得分:1)

每当刷新时,我的Angular SPA上都会出现类似的WhiteLabel错误消息。

解决方法是创建一个实现ErrorController的控制器,但必须返回一个转发到 /

的ModelAndView对象,而不是返回String。
@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;
    }
}

答案 12 :(得分:0)

我试图从微服务中调用REST端点,并且使用了resttemplate的 put 方法。

在我的设计中,如果REST端点内发生任何错误,它应该返回JSON错误响应,它在某些调用中有效,但在此 put 调用中无效,它返回了 white标签错误页面

所以我做了一些调查,结果发现了;

Spring尝试了解调用方,如果它是一台机器,则返回JSON响应,或者如果它是浏览器,则返回的是白色标签错误页面 HTML。

结果:我的客户端应用需要向REST端点说调用者是一台机器,而不是浏览器,因此,客户端应用需要在ACCEPT中添加“ application / json ” resttemplate的'put'方法的显式标头。 我将此添加到标题并解决了问题。

我对端点的呼叫:

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

对于上述调用,我必须在标头参数下方添加。

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

或者我也尝试更改put来交换,在这种情况下,exchange调用也为我添加了相同的标头并解决了问题,但我不知道为什么:)

restTemplate.exchange(....)

答案 13 :(得分:0)

我使用的是Spring Boot版本2.1.2,并且errorAttributes.getErrorAttributes()签名对我不起作用(在acohen的回应中)。我想要一个JSON类型的响应,所以我做了一些挖掘,发现此方法完全符合我的需要。

我从此线程以及此blog post中获得了大部分信息。

首先,我创建了一个CustomErrorController,Spring会在其中寻找任何错误。

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
}

最后,我不得不关闭application.properties文件中的Whitelabel。

server.error.whitelabel.enabled=false

这甚至可以用于xml个请求/响应。但是我还没有测试过。自从创建RESTful API以来,它确实满足了我的期望,并且只想返回JSON。