Leveraging the Spring MVC 3.1 HandlerMethodArgumentResolver interface

A familiar problem when implementing a REST server, is that your framework limits what you can do. Sometimes, this problem can be mitigated (not solved) by reformulating (i.e. changing) your business needs. For example, you can reformulate save multiple changes to an invoice and its invoice lines with one click on a save button to save each of multiple changes to an invoice and its invoice lines as separate UI actions. Unfortunately, this change increases your audit trail and thus technology trumps business needs.

Another limit is that conversions have no context. This makes the conversions easier, but also makes functionality like partial updates impossible. That is, it is not possible to that a request body can contain any subset of the changeable properties of a resource, and that all properties that are left out are left at their current values. The default Spring implementation, for example, treats undefined properties as set to their default value. Our goal was to change that to keep the current value in the database.

In this in-depth technical article, I will show you how the new Spring 3.1 interface HandlerMethodArgumentResolver can be used to remove such framework limits. The result is that your business needs are again in control, not the technology.


Spring MVC 3.0 supports REST using the annotation @RequestMapping. This annotation is also used to map normal web application requests to a method of an @Controller bean. With @RequestMapping you can specify the URL being mapped and the HTTP method that a controller method understands. You can also use the annotations @PathVariable and @RequestParam to extract URL templates and request parameters from requests, respectively. The pièce de résistance for REST are the annotations @RequestBody and @ResponseBody, which map Java classes from the request body, respectively to the response body.

If you look at the code, you will see that the translation from the request to the invocation of the controller method is done using a big if/else statement in the class HandlerMethodInvoker (used in AnnotationMethodHandlerAdapter). Not the prettiest solution, and nearly impossible to extend. You can augment some functionality by using AOP, but nothing more.

Spring 3.1

Spring 3.1 will improve this by using a new class, RequestMappingHandlerAdapter, which implements a strategy pattern using the interface HandlerMethodArgumentResolver. The old/current implementation, AnnotationMethodHandlerAdapter, will remain for backward compatibility.

The core of the new implementation (at least for developers) is the interface HandlerMethodArgumentResolver. This interface has two methods: supportsParameter(MethodParameter) to check if a method parameter is supported, and resolveArgument(MethodParameter, ModelAndViewContainer, NativeWebRequest, WebDataBinderFactory) to actually resolve the method parameter from the request. Default implementations exist for all supported parameters of @RequestMapping annotated methods.

The class RequestMappingHandlerAdapter checks all method parameters against its lists of custom and default HandlerMethodArgumentResolver instances, and the first one that says it supports the method parameter will be used to resolve it.

This new interface gives us some very nice opportunities. I will explain some of them by demonstrating how easy it is to implement your own HandlerMethodArgumentResolver. The examples will show how to extend the REST framework provided by Spring, including adjusting the behavior of the existing Spring implementations.

The Spring version we are using is the latest and greatest, so first we need to add the Spring snapshot repository to our pom.xml:

And finally, we will need to adjust the Spring version of our dependencies to: 3.1.0.BUILD-SNAPSHOT

First example: ValidatingRequestBodyMethodArgumentResolver

One problem found when implementing a REST server, is that of input validation. Especially for objects, it is common to want to use the JSR-303 @Valid annotation to ensure your input is valid. Spring currently has an open bug, SPR-6709, which states that the @Valid annotation on an @RequestBody parameter does not work. Recent activity indicates it will not be with us much longer, but it is a good example to extend existing functionality.

Below is a class we have implemented to solve this problem. It delegates the translation of the request body to the original class, RequestResponseBodyMethodProcessor, and then validates the result if needed:

In this class, the delegation is clearly visible. The injected dependency to RequestMappingHandlerAdapter seems unfortunate, but it handles the underlying HttpMessageConverter implementations much better than we could do. Finally, the exception class ValidationException translates the JSR-303 constraint violations into a form we want.

Lastly, we need to configure Spring MVC to use our class. We use an XML configuration, which looks like this:

The end result is that @Valid and @RequestBody play nice together.

Second example: PathEntityMethodArgumentResolver

Another thing we encounter regularly, is that we want to issue a POST request to a URL to execute an action on a domain object. As we prefer not to repeat the code to retrieve the domain object, we’ve created an annotation @PathEntity so we can do this:

Granted, we could also do this by overriding the Spring ConversionService, but as we’ll see in the next example this approach has it’s advantages. The code for the @PathEntity annotation and the PathEntityMethodArgumentResolver to handle it is this:

And this is the class to resolve parameters annotated with @PathEntity:

Registering this MethodHandlerArgumentResolver is as usual:

With these two classes in place, we can identify our domain objects with our REST resources (URL’s). When the controller method is invoked, we have an instance of the domain entity the URL represents. Note that outside a transaction, this entity is a detached entity (this is prescribed by the JPA specification). So we still need to call EntityManager.merge(Object) to persist any changes.

Third example: RequestEntityMethodArgumentResolver

For CRUD operations, a PUT request to a URL is common and usually overwrites the entire object. In our case however, this is not possible: some object properties are read-only, and others can only be written if the object has a certain status. So what we need is a _partial_ update.

And although it is usually possible to omit fields from the request body, this does not do what we want. What happens is for missing fields, use the default value from the constructor. But what we want is: for missing fields, to not change the value in the database.

We’ve created an annotation @RequestEntity to handle these parameters. Like @PathEntity, a URL template is tied to a domain entity, but now the request body is used to update the (detached) record. An example usage would be:

This controller method now only has to call the service method that updates the database. The code looks like this:

The code to handle this annotation extends our PathEntityMethodArgumentResolver from the previous example:

CRUD applications

The provided examples show the building blocks to reduce a CRUD application to almost no code beyond searching:

The @RequestBody annotation combined with @Valid (see the first example) ensure that the controller only needs to save the record.
The @PathEntity annotation in the second example already provides a loaded record, so the controller can simply return it. Only returning multiple records (i.e. searches) requires more code.
The @RequestEntity annotation in the third example provides a detached, updated and optionally validated record. This includes partial updates The controller method only has to save it.
The @PathEntity annotation provides a record, so it can simply be removed.

As you can see, this means that implementing CRUD has become as trivial as calling your persistence layer. And as an added bonus, the more complex use cases are now also easier to implement: only the call to your business method is needed.


The examples in this article show that it is easy to extend the default Spring functionality to extract any information you want from the request. You can augment the existing functionality with, for example, JSR-303 validations. Or you can completely roll your own solution, including merging the request information with existing data. Combined with the generic Spring concept that any REST call is a method invocation, anything is possible. Your business needs are in control, not the technology.

Oscar Westra van Holthe - Kind – has written 12 posts on this site.
The blood of the mathematician runs thick through Oscar's veins. There are few algorithms that do not reveal themselves under his scrutiny. A shrewd observer of a problem domain with a quick mind for understanding its intricacies, Oscar is a favorite for discussing architecture issues and finding solutions for problems found.

Oscar understands the need for Don't Repeat Yourself and goes a long way towards implementing the best solution for the customer. He is not one for cutting corners, preferring the long-term solution over the quick fix.

He has a mindset for the quality approach, aspiring for high test coverage, architecture compliance and low complexity. Oscar helps his team to live up to these high standards, by coaching and mentoring.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">