How to show custom 404 page when user enters invalid URL in spring boot application?

14,193

Solution 1

First off, define an exception for each especial HTTP error you're going to handle. Here i'm just defining one for handling 404 Not Found case:

public class NotFoundException extends RuntimeException {}

To replace the default Spring Boot's error handling mechanism completely, we can implement ErrorController. Instead of just implementing the ErrorController, here i'm extending AbstractErrorController, which implements the ErrorController and provides some auxiliary methods like getStatus().

Anyway, the basic idea is to handle all errors using an endpoint, say /error, and throw those pre-defined exceptions in case of their corresponding HTTP status codes:

@Controller
public class CustomErrorController extends AbstractErrorController {
    private static final String ERROR_PATH=  "/error";

    @Autowired
    public CustomErrorController(ErrorAttributes errorAttributes) {
        super(errorAttributes);
    }

    /**
     * Just catching the {@linkplain NotFoundException} exceptions and render
     * the 404.jsp error page.
     */
    @ExceptionHandler(NotFoundException.class)
    public String notFound() {
        return "404";
    }

    /**
     * Responsible for handling all errors and throw especial exceptions
     * for some HTTP status codes. Otherwise, it will return a map that
     * ultimately will be converted to a json error.
     */
    @RequestMapping(ERROR_PATH)
    public ResponseEntity<?> handleErrors(HttpServletRequest request) {
        HttpStatus status = getStatus(request);

        if (status.equals(HttpStatus.NOT_FOUND))
            throw new NotFoundException();

        return ResponseEntity.status(status).body(getErrorAttributes(request, false));
    }

    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }
}

Of course, this solution is only suitable for Traditional Deployment. If you're planning to use an Embedded Servlet Container, you're better off defining an EmbeddedServletContainerCustomizer.

Solution 2

Whould you like to add this @Bean to your spring application config, like this :

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {

            ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error404.html");
            container.addErrorPages(error404Page);

        }
    };
}

and put error404.html in your static folder.

Reference : http://www.sporcic.org/2014/05/custom-error-pages-with-spring-boot/

Solution 3

Here you go

@RestController
public class RestErrorController implements ErrorController{

private static final String PATH = "/error";

@Autowired
private ErrorAttributes errorAttributes;

@RequestMapping(value=PATH,method=RequestMethod.GET)
public ApiErrorExtended error(HttpServletRequest request, HttpServletResponse response){
     return new ApiErrorExtended( response.getStatus(),getErrorAttributes(request, true));
}

private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
    RequestAttributes requestAttributes = new ServletRequestAttributes(request);
    return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
}  

public String getErrorPath() {
    return PATH;
} 
}

This is my rest error controller. You can modify it to return whatever u want.

Share:
14,193
ashishjmeshram
Author by

ashishjmeshram

Updated on June 26, 2022

Comments

  • ashishjmeshram
    ashishjmeshram almost 2 years

    I am using java config in spring boot, spring security application. I have configured the error controller as below. But whenever, I enter an invalid URL it goes to error.jsp, which is configured to handle the errors in the application:

    @Controller
    public class AppErrorController implements ErrorController {
    
        private static final String PATH = "/error";
    
        @RequestMapping(value = "/pageNotFound", method = { RequestMethod.GET, RequestMethod.POST })
        public String pageNotFound() {
            return "pageNotFound";
        }
    
        @RequestMapping(value = "/accessDenied", method = { RequestMethod.GET, RequestMethod.POST })
        public String accessDenied() {
            return "accessDenied";
        }
    
        @RequestMapping(value = PATH)
        public String error() {
            return "error";
        }
    
        @Override
        public String getErrorPath() {
            return PATH;
        }
    }
    

    web.xml

    <error-page>
        <error-code>404</error-code>
        <location>/pageNotFound</location>
    </error-page>
    
    <error-page>
        <error-code>500</error-code>
        <location>/error</location>
    </error-page>
    

    404 is never thrown when the invalid URL is entered.

    Also, I am not using embedded tomcat. I am deploying war to the external tomcat. I have this in my application.yml file:

    server:
        error:
            whitelabel:
                enabled: false
    

    Below is the log in case if I enter a invalid URL. There is no error. It just redirects to /error in case of invalid URL:

    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.b.c.web.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@371ef2a3
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/donotexisturl'; against '/static/**'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/donotexisturl'; against '/i18n/**'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@b8db0c9d: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='[email protected]', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@6e929f31
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /donotexisturl' doesn't match 'POST /logout
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
    2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /donotexisturl' doesn't match 'POST /checklogin
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 7 of 13 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.AnonymousAuthenticationFilter  : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='[email protected]', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /donotexisturl' doesn't match 'POST /logout
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/donotexisturl'; against '/login**'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/donotexisturl'; against '/error**'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/donotexisturl'; against '/checklogin**'
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /doNotExistURL; Attributes: [fullyAuthenticated]
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='[email protected]', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.access.vote.UnanimousBased  : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6ad88564, returned: 1
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.access.vote.UnanimousBased  : Voter: org.springframework.security.access.vote.AuthenticatedVoter@19007bb6, returned: 0
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.access.vote.UnanimousBased  : Voter: com.sts.app.core.user.security.AccessDecisionVoterImpl@1465b821, returned: 1
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /doNotExistURL reached end of additional filter chain; proceeding with original chain
    2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/gen/doNotExistURL]
    2016-03-15 10:02:45.063 DEBUG 9997 --- [io-8080-exec-22] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /doNotExistURL
    2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/doNotExistURL]
    2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] o.s.w.s.handler.SimpleUrlHandlerMapping  : Matching patterns for request [/doNotExistURL] are [/**]
    2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] o.s.w.s.handler.SimpleUrlHandlerMapping  : URI Template variables for request [/doNotExistURL] are {}
    2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapping [/doNotExistURL] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@87dd2cb]]] and 1 interceptor
    2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/gen/doNotExistURL] is: -1
    2016-03-15 10:02:45.077 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet        : Successfully completed request
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.b.c.web.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@371ef2a3
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.b.c.web.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.core.ApplicationHttpRequest@20ae74b1
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/static/**'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/i18n/**'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@b8db0c9d: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='[email protected]', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /error' doesn't match 'POST /logout
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
    2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /error' doesn't match 'POST /checklogin
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 7 of 13 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.AnonymousAuthenticationFilter  : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='[email protected]', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}'
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy        : /error reached end of additional filter chain; proceeding with original chain
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/gen/error]
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
    2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String com.sts.app.core.common.web.AppErrorController.error()]
    
  • SeaBiscuit
    SeaBiscuit about 8 years
    Try value=404 instead /pageNotFound see if that helps edited : value = /error
  • SeaBiscuit
    SeaBiscuit about 8 years
    Did u try removing <error-page> <error-code>404</error-code> <location>/pageNotFound</location> </error-page> <error-page> <error-code>500</error-code> <location>/error</location> </error-page> all together? I believe 404 will be resolved by default. Anyways i am gonna take a closer look at my config. when i get back to my pc.
  • ashishjmeshram
    ashishjmeshram about 8 years
    I am not using embedded tomcat. Will this still apply?
  • ekem chitsiga
    ekem chitsiga about 8 years
    What excpetion do you get when your remove the error pages in your web.xml.Probably Spring is throwing another exception wihich is not 404 due to a setup error. Post the error being displayed on tomcat`s default error page
  • ashishjmeshram
    ashishjmeshram about 8 years
    I have tried that also. Does not work. Actually, it used to work in other non spring boot apps.
  • avojak
    avojak almost 6 years
    Ironically that link is now dead.
  • Shailesh Vikram Singh
    Shailesh Vikram Singh over 2 years
    EmbeddedServletContainerCustomizer is not available in Spring Boot 2