Spring MVC may throw a number of exceptions internally while processing a request. These exceptions are handled by DefaultHandlerExceptionResolver. The important aspect of this resolver is that it translates the internal exception into a specific HTTP status code. It uses HttpServletResponse.sendError(statusCode), which causes the server's default error page to display along with the status code and error message. It does not include the exception stack trace.
The status codes are especially important for automated clients (as compared to browser-based human clients), which can apply their own logic automatically based on the status code received in the response. Check out the list of Spring's internal exception types along with their status codes here.
This exception resolver is enabled by default in the DispatcherServlet.
Example
The Controller
In the first handler, we purposely set the wrong value in @PathVariable("testId") instead of "id". This causes a MissingPathVariableException (status code 500, Internal Server Error) because Spring cannot find a matching URI template variable to bind.
In the second handler the consumes = "application/json" attribute restricts which handler matches based on the request's Content-Type header. When the incoming Content-Type doesn't match anything the handler declares it consumes, Spring MVC throws HttpMediaTypeNotSupportedException
package com.logicbig.example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
public class ExampleController {
@RequestMapping("/test/{id}")
@ResponseBody
public String handleRequest (@PathVariable("testId") int id) throws Exception {
return "testId: " + id;
}
@RequestMapping(value = "/test2",
method = RequestMethod.POST,
consumes = "application/json")
@ResponseBody
public String handleRequest(@RequestBody String body) throws Exception {
return "body: " + body;
}
}
To try examples, run embedded Jetty (configured in pom.xml of example project below):
mvn jetty:run
Output
/test/{id}
$ curl -s "http://localhost:8080/test/2" <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/> <title>Error 500 Missing URI template variable 'testId' for method parameter of type int</title> </head> <body><h2>HTTP ERROR 500 Missing URI template variable 'testId' for method parameter of type int</h2> <table> <tr><th>URI:</th><td>/test/2</td></tr> <tr><th>STATUS:</th><td>500</td></tr> <tr><th>MESSAGE:</th><td>Missing URI template variable 'testId' for method parameter of type int</td></tr> <tr><th>SERVLET:</th><td>dispatcher</td></tr> </table> <hr/><a href="https://eclipse.org/jetty">Powered by Jetty:// 9.4.53.v20231009</a><hr/>
</body> </html>
/test2
$ curl -s -X POST http://localhost:8080/test2 -H "Content-Type: text/plain" -d "hello" <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/> <title>Error 415 Unsupported Media Type</title> </head> <body><h2>HTTP ERROR 415 Unsupported Media Type</h2> <table> <tr><th>URI:</th><td>/test2</td></tr> <tr><th>STATUS:</th><td>415</td></tr> <tr><th>MESSAGE:</th><td>Unsupported Media Type</td></tr> <tr><th>SERVLET:</th><td>dispatcher</td></tr> </table> <hr/><a href="https://eclipse.org/jetty">Powered by Jetty:// 9.4.53.v20231009</a><hr/>
</body> </html>
Accessing /test2 with wrong HTTP method throws HttpRequestMethodNotSupportedException:
$ curl -s "http://localhost:8080/test2" <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/> <title>Error 405 Request method 'GET' not supported</title> </head> <body><h2>HTTP ERROR 405 Request method 'GET' not supported</h2> <table> <tr><th>URI:</th><td>/test2</td></tr> <tr><th>STATUS:</th><td>405</td></tr> <tr><th>MESSAGE:</th><td>Request method 'GET' not supported</td></tr> <tr><th>SERVLET:</th><td>dispatcher</td></tr> </table> <hr/><a href="https://eclipse.org/jetty">Powered by Jetty:// 9.4.53.v20231009</a><hr/>
</body> </html>
Example ProjectDependencies and Technologies Used: - spring-webmvc 7.0.6 (Spring Web MVC)
Version Compatibility: 4.2.0.RELEASE - 7.0.6 Version compatibilities of spring-webmvc with this example: Versions in green have been tested.
- jakarta.servlet-api 6.1.0 (Jakarta Servlet API documentation)
- JDK 25
- Maven 3.9.11
|