Spring Boot - Tomcat error handling
The default (maybe even recommended?) behaviour for Spring Boot is to package your web application as a JAR with a bundled Tomcat - following the increasingly popular pattern of "Application Servers are Dead" - a more extreme version of one-app-per-app-server pattern I guess. However, by and large I am still using Tomcat instances (although usually still one-app-per-server) so I am building WAR files for deployment.So error handling. Normally, in our web.xml we would define errorPages for response codes, exception types etc, that Tomcat would be able to forward any response code/exception that comes from your application back into an end-point within your application so you can display a custom error page and handle any additional logging etc.
Now for Spring Boot (and Spring 4 generally) there is a shift away from XML and a lot of effort has been put in to make it possible to create web apps with out a single XML file in sight. This includes the error page mappings - so if you want to define custom mappings you can simply create an error configuration file as so:
Simple right? Now that all makes sense if we are running tomcat bundled with our app - we can use this configuration to configure Tomcat and everything would work as expected - but what about if we are deploying a built WAR file to a Tomcat instance? How can Spring be configuring Tomcat's error page mapping? To me it just seemed too magical, but as you might expect, there is a simple answer: ErrorPageFilter - This is just a default Filter that is added that intercepts all requests with error codes/exceptions and forwards it to the correct endpoint. From the comment at the top of the Filter:
* A special {@link AbstractConfigurableEmbeddedServletContainer} for non-embedded | |
* applications (i.e. deployed WAR files). It registers error pages and handles | |
* application errors by filtering requests and forwarding to the error pages instead of | |
* letting the container handle them. Error pages are a feature of the servlet spec but | |
* there is no Java API for registering them in the spec. This filter works around that by | |
* accepting error page registrations from Spring Boot's | |
* {@link EmbeddedServletContainerCustomizer} (any beans of that type in the context will | |
* be applied to this container). |
A simple solution that will work for standalone JARs or deployed WARs.
0 comments: