ArgumentResolver Spring
Recently I came across Argument Resolver in Spring.
It has got two versions: 1) Spring 3.2
                                          2) Spring 4.0
The scenario was such that for every handler method, I need a particular Object in every method.
So, with the help of Spring Argument Resolver Architecture, I annotate that Particular Type with a Custom annotation
for identifying that Particular Type and populating it.
Without annotation By inspecting Only the type of the Parameter too, this end could be achieved.
The configuration is as follows:
Spring 3.2:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="customArgumentResolver" ref="dataInjectArgResolver"/> </bean> <bean id="dataInjectArgResolver" class="org.springSecurity.controller.CustomWebHandlerArgumentResolver"/> public class CustomWebHandlerArgumentResolver implements WebArgumentResolver { @Override public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest request) throws Exception { // TODO Auto-generated method stub HttpServletRequest httpServletRequest = (HttpServletRequest)request.getNativeRequest(); if(methodParameter.hasParameterAnnotation(DataInject.class)) { return "DATA INJECT old"; } if(methodParameter.hasParameterAnnotation(DataInjectNew.class)) { if(httpServletRequest.getSession(false) != null) { System.out.println("===== User_code:"+(httpServletRequest.getSession(false)).getAttribute("USER_CODE")); } DataInjectObject dataInjectObject = new DataInjectObject(); dataInjectObject.setId(999); dataInjectObject.setName("MIC"); return dataInjectObject; } return WebArgumentResolver.UNRESOLVED; } }Spring 4.0:
<mvc:annotation-driven conversion-service="conversionService"> <mvc:argument-resolvers> <bean class="org.springSecurity.controller.CustomHandlerArgumentResolver"></bean> </mvc:argument-resolvers> </mvc:annotation-driven> public class CustomHandlerArgumentResolver implements HandlerMethodArgumentResolver { @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer meAndViewContainer, NativeWebRequest webRequest, WebDataBinderFactory dataBinderFactory) throws Exception { // TODO Auto-generated method stub System.out.println(" ####### In Resolve Argument method of CustomHandlerArgumentResolver ###### "); return "DATA-INJECT"; } @Override public boolean supportsParameter(MethodParameter methodParameter) { // TODO Auto-generated method stub System.out.println(" ####### In Supports method of CustomHandlerArgumentResolver #### "); return (methodParameter.getParameterAnnotation(DataInject.class)!=null); } }Now, in Spring 4.0, the <mvc:annotation-driven> automatically configures
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter and adds it to the ApplicationContext.
As evident from both the Argument Handler implementation that, based on the Type of Custom annotation,
the population of the desired Object takes place by ruturning an Object of Compatible type, Only in Spring 4.0,
the HandlerMethodArgumentResolver implementation is bit more sophisticated as supportsParameter() checks for the
compatible type before the API calls for resolveArgument() method, unlike Spring 3.2 where this detection of compatible
Type is to be done Programmatically and for an incompatible type "WebArgumentResolver.UNRESOLVED" is returned.
One of the Important Point to notice is, that in both the resolveArgument(), the request Type id NativeWebRequest
and HttpServletRequest can be fetched from it using its API.
The Custom Annotations used here, the code is:
@Target(value=ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface DataInject { String value() default ""; } @Target(value=ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface DataInjectNew { String value() default ""; }The Controller Method looks like:
@Controller public class BaseControllerNew { @RequestMapping(value="/SecureMethodNew" , method=RequestMethod.GET) public ModelAndView secureMethodNew(HttpServletRequest request,@DataInject("dataInject") String dataInject,@DataInjectNew("dataInjectNew") DataInjectObject dataInjectNew) throws Exception { System.out.println(" ============ The value of Data Inject is:"+dataInject+"\n ==========dataInjectNew:"+dataInjectNew); System.out.println(" **** Secure Method New Entered **** "); //secureService.performService(); ModelAndView mv = new ModelAndView(); mv.addObject("msg", "New Controller BaseControllerNew is invoked"); mv.setViewName("SecureMethSuccess"); return mv; } } public class DataInjectObject { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "DataInjectObject [id=" + id + ", name=" + name + "]"; } }This is in short a working example of Spring Argument Resolver. Any Views and thoughts regading this Post
will always be appriciated. Please feel free to post your ideas, and Till then Happy Coding.
Comments
Post a Comment