Reputation: 13540
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
Upvotes: 194
Views: 473766
Reputation: 1008
Custom error page in JSON format for Spring Boot > 2.3.0
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);
}
}
Upvotes: 1
Reputation: 670
I literally missed to add the @RestController annotation in my code somehow. Silly as it may sound, but worth keeping written down somewhere if you ask me, just in-case if you miss that one in a rush..
@RestController
public class MyApiController implements MyApi {
.
.
Upvotes: 0
Reputation: 31
We can easily handle white label error in Java Spring boot. Just add this class in configuration file..
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"));
};
}
}
Upvotes: 0
Reputation: 1723
Solution posted by geoand works for me. In addition to this, if you want to redirect to any specific page then you may use this.
@RequestMapping(value = PATH)
public void error(HttpServletResponse response) {
response.sendRedirect("/"); //provide your error page url or home url
}
Full Code snippet below:
@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: Since, unable to edit above answer, hence posting this as new answer.
Upvotes: 1
Reputation: 131
Best option would be to create a HTML page (JSP,THYMELEAF) with the name "error.html", it would redirect every whitelable error to this page . You can customize it after .
Upvotes: 0
Reputation: 488
I had a similar issue WhiteLabel Error message on my Angular SPA whenever I did a refresh.
The fix was to create a controller that implements ErrorController but instead of returning a String, I had to return a ModelAndView object that forwards to /
@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;
}
}
Upvotes: 3
Reputation: 165
Spring Boot by default has a “whitelabel” error page which you can see in a browser if you encounter a server error. Whitelabel Error Page is a generic Spring Boot error page which is displayed when no custom error page is found.
Set “server.error.whitelabel.enabled=false” to switch of the default error page
Upvotes: 3
Reputation: 1397
I am using Spring Boot version 2.1.2 and the errorAttributes.getErrorAttributes()
signature didn't work for me (in acohen's response). I wanted a JSON type response so I did a little digging and found this method did exactly what I needed.
I got most of my information from this thread as well as this blog post.
First, I created a CustomErrorController
that Spring will look for to map any errors to.
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;
}
}
Second, I created a CustomHttpErrorResponse
class to return the error as 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
}
Finally, I had to turn off the Whitelabel in the application.properties
file.
server.error.whitelabel.enabled=false
This should even work for xml
requests/responses. But I haven't tested that. It did exactly what I was looking for since I was creating a RESTful API and only wanted to return JSON.
Upvotes: 5
Reputation: 85351
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.
Upvotes: 3
Reputation: 337
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(....)
Upvotes: 1
Reputation: 3132
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
Upvotes: 58
Reputation: 817
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
For Spring Boot < 2.0, the class is located in package org.springframework.boot.autoconfigure.web
.
Upvotes: 36
Reputation: 11234
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
Upvotes: 14
Reputation: 4427
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.
Upvotes: 13
Reputation: 71
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
Upvotes: 7
Reputation: 29
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
Upvotes: 2
Reputation: 3193
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);
}
}
Upvotes: 46
Reputation: 1373
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.
Upvotes: 19
Reputation: 64011
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.
Upvotes: 273