弹簧启动删除白标错误页

我试图删除白色标签错误页面,所以我所做的是创建一个控制器映射为“/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 文件,仍然得到相同的错误

383523 次浏览

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

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

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

@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的实现时,SpringBoot 会自动将 BasicErrorController注册为 SpringBean。

要查看这个事实,只需导航到 ErrorMvcAutoConfiguration.basicErrorController 给你

您可以通过指定:

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

文件

对于 Spring Boot < 2.0,该类位于包 org.springframework.boot.autoconfigure.web中。

如果你想要一个更加“ 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 doc ‘ was’wrong (they have since fix it) :

要关闭它,可以设置 启用了 error.whitelabel = false

应该是

要关闭它,可以设置 支持 server.error.whitelabel = false

= false

将上面的行包含到参考资料文件夹 application.properties 中

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

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

<!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创建一个拦截器来传递其他变量

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

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

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

这取决于你的弹簧启动版本:

SpringBootVersion < = 1.2时使用 error.whitelabel.enabled = false

SpringBootVersion > = 1.3时,使用 server.error.whitelabel.enabled = false

我尝试从微服务调用 REST 端点,并使用 resttemplate 的 放下方法。

在我的设计中,如果 REST 端点内发生任何错误,它应该返回一个 JSON 错误响应,它对一些调用起作用,但对这个 放下调用不起作用,它返回的是 白色标签错误页

所以我做了些调查,发现

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

结果: 我的客户端应用程序需要对 REST 端点说,调用者是一台机器,而不是一个浏览器,因此客户端应用程序需要为 resttemplate 的“ put”方法明确地在 ACCEPT 头中添加“ 应用程序/json”。 我把它添加到标题中并解决了这个问题。

我对终点的呼吁:

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

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

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

或者我也试图改变把交换,在这种情况下,交换电话为我添加了相同的头,也解决了问题,但我不知道为什么:)

restTemplate.exchange(....)

这里有一个替代方法,它非常类似于在 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

我使用的是 SpringBoot2.1.2版本,errorAttributes.getErrorAttributes()签名对我不起作用(在 acohen 的回应中)。我想要一个 JSON 类型的响应,所以我做了一些深入的研究,发现这个方法完全符合我的需要。

我的大部分信息来自这个帖子和这个 博客文章

首先,我创建了一个 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
}

最后,我不得不在 abc 0文件中关闭 Whitelabel。

server.error.whitelabel.enabled=false

这甚至可以用于 xml请求/响应。但我还没测试过。它完全符合我的要求,因为我正在创建一个 RESTful API,并且只想返回 JSON。

SpringBoot 默认有一个“ 白标签”错误页面,如果遇到服务器错误,您可以在浏览器中看到该错误页面。“白标签错误页”是一个通用的 Spring 引导错误页,当找不到自定义错误页时将显示该错误页。

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

我有一个类似的问题,白标签错误消息在我的角 SPA 每当我做了刷新。

修复的方法是创建一个实现 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;
}
}

最好的选择是创建一个名为 “ error.html”的 HTML 页面(JSP,THYMELEAF) ,它会将每个可白化的错误重定向到这个页面。之后你可以自定义。

解决方案张贴的 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: 因为无法编辑上面的答案,所以把这个作为新的发布 回答。

我们可以很容易地处理 Java Spring 引导中的白标错误。

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
public class WebRoutingConfig implements WebMvcConfigurer {


@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/urlNotFound")
// the viewName should be specified, in our case we forward to the index.html
.setViewName("forward:/index.html");
}


@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
return container -> {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
"/urlNotFound"));
};
}


}

我确实以某种方式错过了在代码中添加 @ RestController注释。这听起来可能很傻,但是如果你问我的话,我会把它记下来,以防你匆忙中错过了。.

@RestController
public class MyApiController implements MyApi {
.
.


用于 Spring Boot > 2.3.0的 JSON 格式的自定义错误页面

package com.example.api.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.error.ErrorAttributeOptions;
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.RestController;
import org.springframework.web.context.request.WebRequest;


import javax.servlet.http.HttpServletResponse;
import java.util.Map;


@RestController
public class CustomErrorController implements ErrorController {
private static final String PATH = "/error";


@Autowired
private ErrorAttributes errorAttributes;


@RequestMapping(PATH)
public Map<String, Object> error(WebRequest request, HttpServletResponse response) {
return getErrorAttributes(request, true);
}


private Map<String, Object> getErrorAttributes(WebRequest request, boolean includeStackTrace) {
ErrorAttributeOptions options = ErrorAttributeOptions.defaults()
.including(ErrorAttributeOptions.Include.MESSAGE)
.including(ErrorAttributeOptions.Include.EXCEPTION)
.including(ErrorAttributeOptions.Include.BINDING_ERRORS);
if(includeStackTrace){
options = options.including(ErrorAttributeOptions.Include.STACK_TRACE);
}
return this.errorAttributes.getErrorAttributes(request, options);
}
}