2012-09-12 88 views
2

我想创建自定义控制器方法参数注释。Spring mvc - WebArgumentResolver的实现

关注此问题How to pass a session attribute as method argument (parameter) with Spring MVC及以下@Bozho建议,我有这样的事情:

我解析器

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() + "]"); 
    } 
} 

注释

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

简单的控制器来检验一切

@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"; 
    } 
} 

最后,Spring配置

<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"/> 

现在,一切似乎都在为了我,但有可能是我做的,因为执行器的时候,我得到

F0B282C93B74F8FA3F21A51F46D4D4D5 
username 
null 
+0

您可以验证您使用的Spring版本是否为-3.0.5? –

+0

我正在使用Spring 3.1.0 – Andna

+0

好的,你是否也在你的配置文件中有'' - 如果这样AnnotationMethodHandlerAdapter和通过''注册的那个不起作用还有另一种方法来注册参数resolvver –

回答

8
一些愚蠢的错误

使用Spring 3.1.0的ArgumentResolver现在已经改为HandlerMethodArgumentResolver - 在此之前,它曾经是WebArgumentResolver - 相关答案是here

一旦你写一个新的HA ndlerMethodArgumentResolver与当前实现并无太大区别,您可以通过以下方式注册:

<mvc:annotation-driven> 
    <mvc:argument-resolvers> 
     <bean id="sessionAttributeAnnotationResolver" class="..SessionAttributeAnnotationResolver "> 
     </bean>    
    </mvc:argument-resolvers> 
</mvc:annotation-driven> 
+0

添加XML有助于注册我的解析器,但由于某些原因它仍然必须是WebArgumentResolver。 – Adam