So, Spring MVC fans, let’s say you have a @RequestMapping-annotated method in your controller, but you would like to include a custom argument, in addition to the standard ones like Model, HttpServletRequest, and HttpServletResponse.
The solution is to implement a WebArgumentResolver. As an example, we’ll create a CurrentDateWebArgumentResolver; as its name suggests, this resolver will be able to set any Date argument in the controller method to current date.
We have to write
public class ContextExtractingWebArgumentResolver
implements WebArgumentResolver {
@Override
public Object resolveArgument(MethodParameter methodParameter,
NativeWebRequest webRequest) throws Exception {
if (Date.class == methodParameter.getParameterType()) {
return new Date();
}
return UNRESOLVED;
}
}
We then wire-in the argument resolver in our Spring application context configuration file:
<bean class="org.springframework.web.servlet.mvc.annotation.
AnnotationMethodHandlerAdapter"
<property name="customArgumentResolver">
<bean class="package.ContextExtractingWebArgumentResolver"/>
</property>
</bean>
Once done, we can create a @RequestMapping-annotated method in our controller and include the Date argument; that argument will now receive the current date. For example, we can have
@Controller
public class HomeController {
@RequestMapping(value="/index", method=RequestMethod.GET)
public void index(Date date, Model m) {
m.addAttribute("now", date);
}
}
The model that will be passed to the view after making a GET request to the /index URL will include attribute named now; the value of the attribute will be the current time.
Naturally, this is just a simple example and injecting current date is not very enterprisey thing to do, but using the approach I have outlined, you can now set much more useful argument types. Do not forget that the implementation of the WebArgumentResolver is a Spring bean, thus having access to all features available in the Spring application context.