Spring Boot Remove Whitelabel Error Page

2019-01-01 14:58发布

问题:

I\'m trying to remove white label error page, so what I\'ve done was created a controller mapping for \"/error\",

@RestController
public class IndexController {

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

}

But now I\"m getting this error.

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

Don\'t know whether I\'m doing anything wrong. Please advice.

EDIT:

Already added error.whitelabel.enabled=false to application.properties file, still getting the same error

回答1:

You need to change your code to the following:

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

Your code did not work, because Spring Boot automatically registers the BasicErrorController as a Spring Bean when you have not specified an implementation of ErrorController.

To see that fact just navigate to ErrorMvcAutoConfiguration.basicErrorController here.



回答2:

If you want a more \"JSONish\" response page you can try something like that:

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


回答3:

You can remove it completely by specifying:

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

However, do note that doing so will probably cause servlet container\'s whitelabel pages to show up instead :)


EDIT: Another way to do this is via application.yaml. Just put in the value:

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

Documentation

For Spring Boot < 2.0, the class is located in package org.springframework.boot.autoconfigure.web.



回答4:

Spring boot doc \'was\' wrong (they have since fixed it) :

To switch it off you can set error.whitelabel.enabled=false

should be

To switch it off you can set server.error.whitelabel.enabled=false



回答5:

Manual here says that you have to set server.error.whitelabel.enabled to false to disable the standard error page. Maybe it is what you want?

I am experiencing the same error after adding /error mapping, by the way.



回答6:

With Spring Boot > 1.4.x you could do this:

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

but then in case of exception the servlet container will display its own error page.



回答7:

This depends on your spring boot version:

When SpringBootVersion <= 1.2 then use error.whitelabel.enabled = false

When SpringBootVersion >= 1.3 then use server.error.whitelabel.enabled = false



回答8:

In Spring Boot 1.4.1 using Mustache templates, placing error.html under templates folder will be enough:

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

Additional variables can be passed by creating an interceptor for /error



回答9:

Here\'s an alternative method which is very similar to the \"old way\" of specifying error mappings in web.xml.

Just add this to your Spring Boot configuration:

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

}

Then you can define the error pages in the static content normally.

The customizer can also be a separate @Component, if desired.



回答10:

server.error.whitelabel.enabled=false

Include the above line to the Resources folders application.properties

More Error Issue resolve please refer http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page



回答11:

I was trying to call a REST endpoint from a microservice and I was using the resttemplate\'s put method.

In my design if any error occurred inside the REST endpoint it should return a JSON error response, it was working for some calls but not for this put one, it returned the white label error page instead.

So I did some investigation and I found out that;

Spring try to understand the caller if it is a machine then it returns JSON response or if it is a browser than it returns the white label error page HTML.

As a result: my client app needed to say to REST endpoint that the caller is a machine, not a browser so for this the client app needed to add \'application/json\' into the ACCEPT header explicitly for the resttemplate\'s \'put\' method. I added this to the header and solved the problem.

my call to the endpoint:

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

for above call I had to add below header param.

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

or I tried to change put to exchange as well, in this case, exchange call added the same header for me and solved the problem too but I don\'t know why :)

restTemplate.exchange(....)