【问题标题】:Spring aliasFor for Annotations with Target(PARAMETER)Spring aliasFor 用于带有 Target(PARAMETER) 的注释
【发布时间】:2016-08-08 11:53:18
【问题描述】:

我正在尝试使用 spring 的 Meta-annotation 使用 aliasFor 注释来为 springs RequestParam

创建自定义注释

只需“扩展/替换”

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

   @AliasFor("name")
   String value() default "";

   ----
}

加上我的注释

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface QueryParam {

    @AliasFor(annotation = RequestParam.class, attribute = "name")
    String name() default "";

    @AliasFor(annotation = RequestParam.class, attribute = "required")
    boolean required() default false;

    @AliasFor(annotation = RequestParam.class, attribute = "defaultValue")
    String defaultValue() default ValueConstants.DEFAULT_NONE;

}

这样会抛出异常

org.springframework.core.annotation.AnnotationConfigurationException:   @AliasFor declaration on attribute [name] in annotation [package.QueryParam] declares an alias for attribute [name] in meta-annotation [org.springframework.web.bind.annotation.RequestParam] which is not meta-present.

问题是,如果没有在 QueryParam 上注释的 RequestParam,这是行不通的。并且不可能将 RequestParam 作为它的 PARAMETER 目标。

@RequestParam <--This is not possible. 
public @interface QueryParam

那么还有其他方法可以实现吗?

【问题讨论】:

    标签: java spring spring-mvc spring-boot spring-annotations


    【解决方案1】:

    现在基本上你想要实现的目标是不可能的,至少对于 Spring v 4.3.3 主要有两个问题,第一个是像 @RequestParam 这样的注释是用 @Target(ElementType.PARAMETER) 声明的,这使得它不可能用作元注释的一部分。此外,Spring MVC 使用不支持元注释或组合注释的 org.springframework.core.MethodParameter.getParameterAnnotations() 查找方法参数上的注释。但是如果你真的需要一些自定义,你可以使用HandlerMethodArgumentResolver 而不是元注释。

    所以你的代码看起来像

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface QueryParam {
    
       String name() default "";
    
       boolean required() default false;
    
       String defaultValue() default ValueConstants.DEFAULT_NONE;
    
    }
    

    然后使用HandlerMethodArgumentResolver 添加您需要的自定义逻辑。

    public class QueryParamResolver implements HandlerMethodArgumentResolver {
    
       public boolean supportsParameter(MethodParameter parameter) {
           return parameter.getParameterAnnotation(QueryParam.class) != null;
       }
    
       public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
            WebDataBinderFactory binderFactory) throws Exception {
           QueryParam attr = parameter.getParameterAnnotation(QueryParam.class);
           // here you can use any logic which you need
           return webRequest.getParameter(attr.value());
       }
    }
    

    那我们需要注册我们的HandlerMethodArgumentResolver

    @Configuration
    @EnableWebMvc
    public class Config extends WebMvcConfigurerAdapter {
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
          argumentResolvers.add(new QueryParamResolver());
        }
    }
    

    最后让我们使用我们的自定义注解

     @GetMapping("/test")
     public String test(@QueryParam("foo") String foo){
          // something here 
     }
    

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,我为 GetAmpping 输入了错误的包。我必须导入«import org.springframework.web.bind.annotation.GetMapping»。

      【讨论】:

        猜你喜欢
        • 2021-11-15
        • 2022-01-07
        • 1970-01-01
        • 1970-01-01
        • 2019-03-10
        • 2014-05-09
        • 2018-12-30
        • 2014-07-15
        • 1970-01-01
        相关资源
        最近更新 更多