Comprehensive Guide to Exception Handling in Spring Web MVC

Exception management is a critical aspect of web applications, requiring attention on both client and server sides. For robust systems, implementing exception handling at both ends is recommended. This article focuses specifically on managing HTTP request exceptions on the server side using Spring's Web MVC framework.

Common Exception Types

When making HTTP requests in Spring applications, various potential errors can occur. These typically fall into two main categories: service-level exceptions and interface-level exceptions. The latter encompasses numerous scenarios, but ultimately all relate to interface exceptions.

Exceptions can occur at various stages of request processing. This article primarily examines scenarios where network communication functions normally, focusing on the exceptions that arise during request handling.

Spring's DefaultHandlerExceptionResolver.doResolveException method provides detailed handling for these scenarios:

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    if (ex instanceof HttpRequestMethodNotSupportedException) {
        return handleRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request, response, handler);
    }
    else if (ex instanceof HttpMediaTypeNotSupportedException) {
        return handleUnsupportedMediaType((HttpMediaTypeNotSupportedException) ex, request, response, handler);
    }
    else if (ex instanceof HttpMediaTypeNotAcceptableException) {
        return handleUnacceptableMediaType((HttpMediaTypeNotAcceptableException) ex, request, response, handler);
    }
    else if (ex instanceof MissingPathVariableException) {
        return handleMissingPathVariable((MissingPathVariableException) ex, request, response, handler);
    }
    else if (ex instanceof MissingServletRequestParameterException) {
        return handleMissingParameter((MissingServletRequestParameterException) ex, request, response, handler);
    }
    else if (ex instanceof ServletRequestBindingException) {
        return handleBindingException((ServletRequestBindingException) ex, request, response, handler);
    }
    else if (ex instanceof ConversionNotSupportedException) {
        return handleConversionNotSupported((ConversionNotSupportedException) ex, request, response, handler);
    }
    else if (ex instanceof TypeMismatchException) {
        return handleTypeMismatch((TypeMismatchException) ex, request, response, handler);
    }
    else if (ex instanceof HttpMessageNotReadableException) {
        return handleUnreadableMessage((HttpMessageNotReadableException) ex, request, response, handler);
    }
    else if (ex instanceof HttpMessageNotWritableException) {
        return handleUnwritableMessage((HttpMessageNotWritableException) ex, request, response, handler);
    }
    else if (ex instanceof MethodArgumentNotValidException) {
        return handleInvalidArgument((MethodArgumentNotValidException) ex, request, response, handler);
    }
    else if (ex instanceof MissingServletRequestPartException) {
        return handleMissingRequestPart((MissingServletRequestPartException) ex, request, response, handler);
    }
    else if (ex instanceof BindException) {
        return handleBindingError((BindException) ex, request, response, handler);
    }
    else if (ex instanceof NoHandlerFoundException) {
        return handleNoHandlerFound((NoHandlerFoundException) ex, request, response, handler);
    }
    else if (ex instanceof AsyncRequestTimeoutException) {
        return handleAsyncTimeout((AsyncRequestTimeoutException) ex, request, response, handler);
    }
    return null;
}

These exceptions can be organized as follows:

Method Exception Type Description
handleRequestMethodNotSupported HttpRequestMethodNotSupportedException Occurs when an HTTP method is not supported by the endpoint (e.g., POST-only endpoint accessed via GET)
handleUnsupportedMediaType HttpMediaTypeNotSupportedException Happens when the request content type is not supported by any configured message converters
handleUnacceptableMediaType HttpMediaTypeNotAcceptableException Raised when the server cannot generate a response in a format acceptable to the client
handleMissingPathVariable MissingPathVariableException Occurs when a required path variable is missing from the URL pattern. For example: @RequestMapping("/user/**{userId}**") public User getUser(@PathVariable String userId){} Missing the {userId} in the path would trigger this exception
handleMissingParameter MissingServletRequestParameterException Happens when a required request parameter is missing when using @RequestParam
handleBindingException ServletRequestBindingException Thrown during the request binding process
handleConversionNotSupported ConversionNotSupportedException Occurs when Spring cannot find an appropriate editor or converter for a property
handleTypeMismatch TypeMismatchException Happens when attempting to set a property with a value of an incompatible type
handleUnreadableMessage HttpMessageNotReadableException Thrown when HttpMessageConverter.read() fails to process the request body
handleUnwritableMessage HttpMessageNotWritableException Raised when HttpMessageConverter.write() fails to generate the response
handleInvalidArgument MethodArgumentNotValidException Occurs when validation fails on parameters annotated with @Valid
handleMissingRequestPart MissingServletRequestPartException Happens when a multipart request is missing expected parts
handleBindingError BindException General exception related to data binding issues
handleNoHandlerFound NoHandlerFoundException Raised when DispatcherServlet cannot find a matching handler. This occurs when the throwExceptionIfNoHandlerFound property is set to true in the servlet configuration
handleAsyncTimeout AsyncRequestTimeoutException Indicates that an asynchronous request has timed out (typically results in a 503 status)

Spring and Spring Boot frameworks contain numerous additional exception-related classes beyond those listed above. Due to the importance of error handling, virtually all method and processes should include exception handling mechanisms. This article focuses on the most common scenarios relevant to HTTP request processing.

Web MVC Exception Configuration

The Web MVC framework provides several points for exception handling. Let's examine the exception-specific configuration in the Web MVC setup:

@Bean
public ExceptionResolverComposite customExceptionResolver(ContentNegotiationManager negotiationManager) {
    List<HandlerExceptionResolver> resolvers = new ArrayList<>();
    configureCustomExceptionResolvers(resolvers);
    
    if (resolvers.isEmpty()) {
        addDefaultExceptionResolvers(resolvers, negotiationManager);
    }
    
    extendExceptionResolvers(resolvers);
    
    ExceptionResolverComposite composite = new ExceptionResolverComposite();
    composite.setOrder(0);
    composite.setExceptionResolvers(resolvers);
    return composite;
}

/**
 * Method to configure custom exception resolvers.
 * Adding resolvers to the list disables the default resolvers.
 * @param resolvers List to add exception resolvers to (initially empty)
 */
protected void configureCustomExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
}

/**
 * Method to add default exception resolvers.
 * Adds the following exception resolvers:
 *  \* - ExceptionHandlerResolver for handling exceptions through @ExceptionHandler methods \*
- ResponseStatusResolver for exceptions annotated with @ResponseStatus \*
- DefaultExceptionResolver for resolving known Spring exception types \*
 */
protected final void addDefaultExceptionResolvers(List<HandlerExceptionResolver> resolvers,
        ContentNegotiationManager negotiationManager) {

    ExceptionHandlerResolver handlerResolver = createExceptionHandlerResolver();
    handlerResolver.setContentNegotiationManager(negotiationManager);
    handlerResolver.setMessageConverters(getMessageConverters());
    handlerResolver.setCustomArgumentResolvers(getArgumentResolvers());
    handlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers());
    
    if (jackson2Present) {
        handlerResolver.setResponseBodyAdvice(
                Collections.singletonList(new JsonViewResponseBodyAdvice()));
    }
    
    if (this.applicationContext != null) {
        handlerResolver.setApplicationContext(this.applicationContext);
    }
    
    handlerResolver.afterPropertiesSet();
    resolvers.add(handlerResolver);

    ResponseStatusResolver statusResolver = new ResponseStatusResolver();
    statusResolver.setMessageSource(this.applicationContext);
    resolvers.add(statusResolver);

    resolvers.add(new DefaultExceptionResolver());
}    

Through the Web MVC mechanism, you can customize exception handling by either overriding the exception resolver bean or implementing the configureCustomExceptionResolvers method to add custom exception resolvers. However, in most cases, the default DefaultExceptionResolver is sufficient for handling common exception scenarios as described earlier.

HTTP Exception Handling in Spring Boot

When developing with Spring Boot, the framework automatically configures a BasicErrorController through its autoconfiguration mechanism. This controller implements the ErrorController interface.

Accoridng to Spring Boot's documentation, you can customize error handling by implementing the ErrorController interface to override the default behavior:

@Controller
public class CustomErrorHandler implements ErrorController {

    @RequestMapping("/error")
    public String manageError(HttpServletRequest request, HttpServletResponse response) {
        int statusCode = response.getStatus();
        
        if (statusCode == 404) {
            return "/error-pages/not-found";
        } 
        else if (statusCode == 403) {
            return "/error-pages/access-denied";
        }
        else if (statusCode == 500) {
            return "/error-pages/server-error";
        }
        
        return "/error-pages/general";
    }
}

It's important to note that the ErrorController code executes after the Web MVC exception handling has been processed.

Alternatively, you can use controller advice annotations for exception handling. For example, you could create a global exception handler using @ControllerAdvice and @ExceptionHandler annotations to manage exceptions across your application.

Conclusion

Spring provides additional mechanisms to prevent common errors, such as validation. While validation can address certain exception scenarios, particularly those involving invalid parameters, it's often unnecessary since such issues should typically be handled on the client side before reaching the server.

Tags: spring-webmvc exception-handling java-web-development spring-boot error-handling

Posted on Thu, 02 Jul 2026 16:57:51 +0000 by mrmigu