【问题标题】:Spring Boot Remove Whitelabel Error PageSpring Boot 移除 Whitelabel 错误页面
【发布时间】:2014-10-10 23:33:11
【问题描述】:

我正在尝试删除白标错误页面,所以我所做的是为“/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 文件,仍然出现同样的错误

【问题讨论】:

  • 看看这个项目github.com/paulc4/mvc-exceptions/blob/master/src/main/java/…,好像他们有错误页面重新映射。
  • 你试过设置spring.resources.add-mappings=false吗?
  • 感谢您的建议,是的,仍然出现同样的错误
  • /error 路径被调用时,你只是想返回一些自定义内容吗?

标签: spring spring-boot


【解决方案1】:

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

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

您的代码不起作用,因为当您没有指定 ErrorController 的实现时,Spring Boot 会自动将 BasicErrorController 注册为 Spring Bean。

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

【讨论】:

  • 遇到了同样的问题,我搜索了 Spring 文档,但没有提到 BasicErrorController。这行得通:)
  • 我必须通过源代码才能找到这个 :-)
  • 谢谢,工作得很好!如果您可以提供任何指示,请进行一个小的后续操作:假设我们进入了这个错误处理程序,因为我们的应用程序中抛出了一些异常(并且 Spring 隐式地将响应代码设置为 500,这是正确的);是否有一种简单的方法可以在此处获取该异常(在返回的错误消息中包含一些详细信息)?
  • 很高兴您发现它很有用!虽然我没有尝试过,但我很确定你可以使用 Spring Boot 的BasicErrorController(见github.com/spring-projects/spring-boot/blob/…)中找到的原理来完成你想要的
  • 嗯,好的,再次感谢!起初我不确定如何获取 ErrorAttributes 对象(包含错误详细信息),但后来我尝试简单地 @Autowiring 它,它可以工作。我现在用的是什么:gist.github.com/jonikarppinen/662c38fb57a23de61c8b
【解决方案2】:

Spring boot doc 'was' 错误(他们已经修复了它):

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

应该是

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

【讨论】:

  • 这将禁用白标错误页面,但 spring boot 将映射端点 /error 无论如何。释放端点/error 设置server.error.path=/error-spring 或其他路径。
【解决方案3】:

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

【讨论】:

  • 在 Spring-Boot v2 中,ErrorController 和 ErrorAttributes 类位于包 org.springframework.boot.web.servlet.error 中,并且 ErrorAttributes#getErrorAttributes 方法签名已更改,请注意对 Spring-Boot 的依赖v1 并可能给出 v2 的提示,谢谢。
  • 更改:私有 Map getErrorAttributes(HttpServletRequest aRequest, boolean includeStackTrace) { RequestAttributes requestAttributes = new ServletRequestAttributes(aRequest); return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace); } By : private Map getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) { WebRequest webRequest = new ServletWebRequest(request);返回 this.errorAttributes.getErrorAttributes(webRequest, includeStackTrace); }
  • 考虑到上述 cmets 的 SimpleErrorController.java 的更新版本可以在此处找到 > gist.github.com/oscarnevarezleal/…
【解决方案4】:

您可以通过指定将其完全删除:

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 org.springframework.boot.autoconfigure.web。

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

    • 是的,我已经设置了 error.whitelabel.enabled=false 但添加 /error 映射后仍然出现相同的错误
    • 这将禁用白标错误页面,但 Spring Boot 无论如何都会映射端点 /error。释放端点/error 设置server.error.path=/error-spring 或其他路径。
    【解决方案6】:

    使用 Spring Boot > 1.4.x 你可以这样做:

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

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

    【讨论】:

      【解决方案7】:

      这取决于你的 Spring Boot 版本:

      SpringBootVersion 1.2 然后使用error.whitelabel.enabled = false

      SpringBootVersion >= 1.3 然后使用server.error.whitelabel.enabled = false

      【讨论】:

        【解决方案8】:

        在使用 Mustache 模板的 Spring Boot 1.4.1 中,将 error.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创建拦截器来传递其他变量

        【解决方案9】:

        我使用的是 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。

        【讨论】:

          【解决方案10】:

          这是另一种方法,它与在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

          【讨论】:

            【解决方案11】:

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

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

            【讨论】:

              【解决方案12】:

              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,但什么也没做。 /src/main/resources 下的 application.properties 文件夹是 suganya sudarsan 试图传达的内容。它似乎也是 Eclipse 中的“热门读物”。
              【解决方案13】:

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

              解决方法是创建一个实现 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;
                  }
              }
              

              【讨论】:

                【解决方案14】:

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

                在我的设计中,如果 REST 端点内发生任何错误,它应该返回 JSON 错误响应,它适用于某些调用,但不适用于此 put 调用,它返回 白色标签错误页面

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

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

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

                我对端点的调用:

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

                对于上面的调用,我必须在下面添加标题参数。

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

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

                restTemplate.exchange(....)
                

                【讨论】:

                  【解决方案15】:

                  最好的选择是创建一个名为 "error.html" 的 HTML 页面 (JSP,THYMELEAF),它将所有可白标错误重定向到此页面。之后可以自定义。

                  【讨论】:

                    【解决方案16】:

                    geoand 发布的解决方案适合我。除此之外,如果您想重定向到任何特定页面,那么您可以使用它。

                    @RequestMapping(value = PATH)
                    public void error(HttpServletResponse response) {
                        response.sendRedirect("/");   //provide your error page url or home url
                    }
                    

                    完整代码如下:

                    @RestController
                    public class IndexController implements ErrorController{
                    
                        private static final String PATH = "/error";
                    
                        @RequestMapping(value = PATH)
                        public void error(HttpServletResponse response) {
                             response.sendRedirect("/");   //provide your error page url or home url
                        }
                    
                        @Override
                        public String getErrorPath() {
                            return PATH;
                        }
                    }
                    

                    PS:由于无法编辑上述答案,因此将其发布为新的 回答。

                    【讨论】:

                      猜你喜欢
                      • 2017-06-03
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2018-06-09
                      • 2018-04-19
                      • 2017-10-06
                      • 2018-07-22
                      相关资源
                      最近更新 更多