2

I wanted to create custom controller method argument annotation.

Following this question How to pass a session attribute as method argument (parameter) with Spring MVC and following @Bozho advice I have something like this:

my resolver

public class SessionAttributeAnnotationResolver implements WebArgumentResolver {

    public Object resolveArgument(MethodParameter parameter,
            NativeWebRequest request) throws Exception {
        System.out.println("I am here");
        Annotation[] parameterAnnotations = parameter.getParameterAnnotations();
        Class<?> parameterType = parameter.getParameterType();

        for (Annotation parameterAnnotation : parameterAnnotations) {
            if (SessionAttribute.class.isInstance(parameterAnnotation)) {
                SessionAttribute sessionAttribute = (SessionAttribute) parameterAnnotation;
                String parameterName = sessionAttribute.value();
                boolean required = sessionAttribute.required();
                HttpServletRequest httprequest = (HttpServletRequest) request
                        .getNativeRequest();
                HttpSession session = httprequest.getSession(false);
                Object result = null;
                if (session != null) {
                    result = session.getAttribute(parameterName);
                }
                if (result == null && required && session == null)
                    raiseSessionRequiredException(parameterName, parameterType);
                if (result == null && required)
                    raiseMissingParameterException(parameterName, parameterType);
                return result;
            }
        }
        return WebArgumentResolver.UNRESOLVED;
    }

    protected void raiseMissingParameterException(String paramName,
            Class<?> paramType) throws Exception {
        throw new IllegalStateException("Missing parameter '" + paramName
                + "' of type [" + paramType.getName() + "]");
    }

    protected void raiseSessionRequiredException(String paramName,
            Class<?> paramType) throws Exception {
        throw new HttpSessionRequiredException(
                "No HttpSession found for resolving parameter '" + paramName
                        + "' of type [" + paramType.getName() + "]");
    }
}

the annotation

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface SessionAttribute {
    String value();
    boolean required() default true;
}

simple controller to test everything

@Controller
@RequestMapping("/test")
public class TestController {

    @RequestMapping(method= RequestMethod.GET)
    public String t(@SessionAttribute("userEntity") UserEntity e2,Model model,HttpServletRequest req){
        System.out.println(req.getSession().getId());
        UserEntity e=(UserEntity) req.getSession().getAttribute("userEntity");
        System.out.println(e.getName());
        System.out.println(e2.getName());
        return "login";
    }
}

and finally, Spring configuration

<beans:bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">     
    <beans:property name="customArgumentResolver" ref="sessionAttributeAnnotationResolver"/>
</beans:bean>
<beans:bean id="sessionAttributeAnnotationResolver" class="pl.meble.taboret.utils.SessionAttributeAnnotationResolver"/>  

now, everything seems in order to me, but there is probably some silly mistake that I done, because when controller is executed, I am getting

F0B282C93B74F8FA3F21A51F46D4D4D5
username
null
Community
  • 1
  • 1
Andna
  • 6,539
  • 13
  • 71
  • 120
  • Can you please verify the version of Spring that you are using -3.0.5? – Biju Kunjummen Sep 12 '12 at 19:34
  • Okay, do you also have `` somewhere in your configuation - if so AnnotationMethodHandlerAdapter and the one registered through `` don't work well together there is another way to register the argumentresolver – Biju Kunjummen Sep 12 '12 at 19:40
  • Yes, I have this line in my .xml configuration file. – Andna Sep 12 '12 at 20:03
  • Is there a way then, to create some bean or method, that the Spring will execute after it initializes bean? This way I could get the container and manually set this property from java code? – Andna Sep 12 '12 at 20:22
  • I have added an answer, can you please see if it helps, if you are not clear on how to implement a `HandlerMethodArgumentResolver`, I can add this information to my answer. – Biju Kunjummen Sep 12 '12 at 20:28

1 Answers1

10

With Spring 3.1.0 the ArgumentResolver has now changed to HandlerMethodArgumentResolver - prior to that it used to be WebArgumentResolver - a related answer is here

Once you have written a new HandlerMethodArgumentResolver which is not very different from your current implementation you can register it this way:

<mvc:annotation-driven>
    <mvc:argument-resolvers>
        <bean id="sessionAttributeAnnotationResolver" class="..SessionAttributeAnnotationResolver ">
        </bean>            
    </mvc:argument-resolvers>
</mvc:annotation-driven>
Community
  • 1
  • 1
Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
  • Adding the XML helped register my resolver, but it still had to be a WebArgumentResolver for some reason. – aakoch Aug 07 '13 at 14:30