≡ Menu
Spring Tutorial MVC – Handling 404 Status

Spring Tutorial MVC – Handling 404 Status

Spring Tutorial – How to Handle Servlet 3.0 + Error pages with Spring MVC

Remember Sharing is caring! So if you get something from this Spring tutorial please share it with others on facebookgoogle+, LinkedIn, Twitter  etc… so it may help them too! :)

If you have a Spring MVC web application that’s configured programmatic-ally; i.e. using Spring JavaConfig.

You’re probably left feeling it’s all or nothing with regards to either Java code or XML for configuration. Many folks ask the question;

So I don’t have a ‘web.xml’ file anymore ? All the configuration is taken care of in the code now! right??’

Well, it’s not the case and infact Spring MVC works just great having web applications configured using Spring JavaConfig and external stuff held in the ‘web.xml’ file.

So, in this Spring tutorial I want to look at an example of Error handling, to be more specific how to handle errors that can occur outside the Spring MVC web application.

For example; the ugly “HTTP Status 404” page you’re greeted with after suffering a typo in your browsers URL.

Don’t get me wrong, your web application should catch and handle correctly any errors that are raised within it but what happens in the scenario, where the end user simply creates a typo in the URL, when trying to access a page of your Spring MVC web application?

Your users will be rewarded with a pretty cryptic and unfriendly 404 page or even worse, it can expose to the outside world the underlying implementation of you web application. Not professional at best and potentially not secure.

This scenario can be dealt with really easily by having the world of programmable configuration, i.e Spring JavaConfig used in Spring MVC, meet with Servlet 3.0 + container XML configuration in a web.xml and allow them to work together for a great solution.

Just to recap, the web.xml file is just a plan old XML file located in the WEB-INF directory of your Spring MVC web application.

So, using the standard Maven directory layout for a web application;

src/main/webapp/WEB-INF/web.xml

The other point to note is the version of the namespace required. It must be 3.0 or greater to work, if you’re programming the Spring MVC configuration using JavaConfig.

Below, should act as a good web.xml template for Servlet 3.0;


<?xml version=<i>"1.0"</i> encoding=<i>"UTF-8"</i>?>

<web-app xmlns:xsi=<i>"http://www.w3.org/2001/XMLSchema-instance"</i>

xmlns=<i>"http://java.sun.com/xml/ns/javaee"</i>

xsi:schemaLocation=<i><a href="http://java.sun.com/xml/ns/javaee%20http:/java.sun.com/xml/ns/javaee/web-app_3_0.xsd">http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd</a> </i>version=<i>"3.0"</i>>

</web-app>

In our scenario we want Spring MVC to handle errors raised outside of or web application;

e.g. When the user enters an incorrect URL for any of our applications pages which results in a status 404 being raised.

In a Servlet 3.0 + container the ‘error-page’ element, acts as a ‘catch-all’ for any errors raised;

<?xml version=<i>"1.0"</i> encoding=<i>"UTF-8"</i>?>

<web-app xmlns:xsi=<i>"http://www.w3.org/2001/XMLSchema-instance"</i>

xmlns=<i>"http://java.sun.com/xml/ns/javaee"</i>

xsi:schemaLocation=<i><a href="http://java.sun.com/xml/ns/javaee%20http:/java.sun.com/xml/ns/javaee/web-app_3_0.xsd">http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd</a> </i>version=<i>"3.0"</i>>

<error-page>
 	<location></location>
</error-page>

</web-app>

What goes in the location element ?

We can use a mapping to a Spring @Controller class with a method annotated with @RequestMapping(“error”), so our location in this example will be ‘/error’.

<error-page>
 	<location>/error</location>
</error-page>

The Spring MVC controller will look something like;

@Controller
class GeneralErrorHandlerController {
		
    @RequestMapping("error")	
    public String handelError(final HttpServletRequest request, final Model model) {
         /**
	  * Process the error details received in the request
	 */

	 // Lets get the status code and uri from the request
	 final Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");		
	 String requestUri = (String) request.getAttribute("javax.servlet.error.request_uri");
          if (requestUri == null) {
	    requestUri = "Unknown";
	  }
	  // create a message to be sent back via the model object.
	  final String message = MessageFormat.format("{0} returned for {1}", 
		statusCode, requestUri); 
		
	   model.addAttribute("errorMessage", message);
        return "errorGeneralView";
	}
}

In the handelError method we pull out a bunch of details like the status code and URI but you can enhance this more yourself by accessing the actual exception which was raised and pull out the message from that.

The only thing left is the implementation of an error page. I’m using a jsp, just as an example but you will probably be using a different technology, the principle is the same.

This basic version just prints out the message composed by the Spring MVC Controller. It displays the status code and URI and gives the user a chance to return to the home page.

(Remember this approach is generic and will be used for any http status!)

<body>
	<div class="errorMessageText">
		<p>
			<c:out value="${errorMessage}" />
		</p>
		<p>The page you requested is not available.</p>

		<p>
			Try returning to the <a href="<c:url value="/"/>">home page</a>.
		</p>
	</div>	
</body>

Thanks for reading!!
Bruce

Remember Sharing is caring! So if you get something from this Spring tutorial please share it with others on facebookgoogle+, LinkedIn, Twitter  etc… so it may help them too! :)

in Blog from the Den, Spring Tutorials

About the author: Bruce is a techie, a gadget geek, programmer, mentor and all round technology nut. He holds two degrees in computer science, with over 25 years in the software business. Currently working freelance as a software engineer and programming mentor. He loves what technology can do for us. Building applications using functional, Object Orientated languages & polyglot persistence helps him reconnect with the feeling of building something tangible. To learn more about Bruce, follow him on Twitter @denofprogram

{ 0 comments… add one }

Leave a Comment