Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot - custom 404 page with standalone tomcat

I am running a Spring boot application inside a standalone tomcat instance, and I am trying to override the error pages. From my understanding, Spring provides a filter ErrorPageFilter that allows me to just setup error pages as normal for Springs EmbeddedServletContainerCustomizer to handle this case exactly.

So I have my standard auto configuration/servlet initializer in one class:

@Configuration
@ComponentScan
@EnableAutoConfiguration(exclude = [ GroovyTemplateAutoConfiguration, SecurityAutoConfiguration, ErrorMvcAutoConfiguration, JmxAutoConfiguration ] )
class Application extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }

(I am using the same class for autoconfiguration and servlet init, which is why i just pass my Application class in the configure method)

Looking at the source code for SpringBootServletInitializer it looks like the ErrorPageFilter class is being added by just extending that class here. I have turned off the ErrorMvcAutoConfiguration - but again, looking at that source code it looks like that is just setting default error pages and not actually setting anything up with the ErrorPageFilter.

I then have my error config file:

@Configuration
class ErrorConfiguration implements EmbeddedServletContainerCustomizer {

    @Override public void customize( ConfigurableEmbeddedServletContainer container ) {
        container.addErrorPages(new ErrorPage( HttpStatus.NOT_FOUND, "/errors/404" ))
    }

However, if I just visit an invalid URL, and I DispatcherServlet can't find a match then I just get tomcats /404.html - not my view linked to "/errors/404" (I have this path mapped to a thymeleaf view template, that works fine - if I navigate to /errors/404 it displays ok)

Any ideas why my custom error page is not working? tracing the logs, I get a line about the ErrorPageFilter being configured and setup ok on application startup, but then no mentions of the filter doing anything when a request comes in.

like image 813
rhinds Avatar asked Dec 09 '14 18:12

rhinds


People also ask

How do I create a 404 page in spring boot?

We first need to create a custom HTML error page. If we save this file in resources/templates directory, it'll automatically be picked up by the default Spring Boot's BasicErrorController. We can be more specific by naming the file with the HTTP status code we want it used e.g. saving the file as 404.

Can we use external Tomcat in spring boot?

Deploying Spring Boot war file on External TomcatYou must have an apache tomcat installed on your computer. If not please download and install it. Once you installed and then go inside the folder of apache tomcat, for my case the path of tomcat is C:\Users\1302143\Downloads\apache-tomcat-8.5.

How do I change my Tomcat to 404?

Create a 404. html page inside tomcat_home>webapps>ROOT>error folder with required content. Test the application: start tomcat and access the home page with localhost:8080/hello and you should see the custom error page displayed.


2 Answers

You can use following code for older versions of spring boot (0.5.x)

  public class ServerCustomization extends ServerProperties {

  @Override
  public void customize(ConfigurableEmbeddedServletContainerFactory factory) {

    super.customize(factory);
    factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
            "/yourpath/error-not-found.jsp"));
    factory.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,
            "/yourpath/error-internal.jsp"));
    factory.addErrorPages(new ErrorPage("/yourpath/error-other.jsp"));
   }
}

Newer spring boot versions (1.X.RELEASE) has some refactoring around ServerProperties. See below,

  public class ServerCustomization extends ServerProperties {

  @Override
  public void customize(ConfigurableEmbeddedServletContainer container) {

    super.customize(container);
    container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
            "/jsp/404.jsp"));
    container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,
            "/jsp/500.jsp"));
    container.addErrorPages(new ErrorPage("/jsp/error.jsp"));
  }

}

Then define a bean to inject ServerProperies.

@Bean
public ServerProperties getServerProperties() {
    return new ServerCustomization();
}

Sample project posted in git

Very Important: If you are using maven to build, You must store all the resource files under src/main/resources folder. Otherwise maven will not add those files to final jar artifact.

like image 124
kamoor Avatar answered Sep 17 '22 19:09

kamoor


You can either use Spring Boot's builtin error view by implementing a view named error, or switch it off by setting error.whitelabel.enabled=false property and implement your own. It's explained more in the docs.

like image 42
gerrytan Avatar answered Sep 19 '22 19:09

gerrytan