Java 在查找控制器方法的注释时,RequestMapping注释导致RequestMethod数组为空

Java 在查找控制器方法的注释时,RequestMapping注释导致RequestMethod数组为空,java,spring,reflection,spring-mvc,annotations,Java,Spring,Reflection,Spring Mvc,Annotations,我们正在构建某种自动自描述REST服务(实时文档生成)。为此,我们有一个控制器方法,它查找所有控制器bean,并获取requestmapping信息,以便在友好的html页面中显示它们 为此,我们使用MetadataReader(通过CachingMetadataReaderFactory创建)获取类的元数据。 当我们获取公共方法的MethodMetaData时,我们会找到RequestMapping注释以及Products和value参数,但是method字段始终是空数组,尽管我们在源代码中配

我们正在构建某种自动自描述REST服务(实时文档生成)。为此,我们有一个控制器方法,它查找所有控制器bean,并获取requestmapping信息,以便在友好的html页面中显示它们

为此,我们使用MetadataReader(通过CachingMetadataReaderFactory创建)获取类的元数据。
当我们获取公共方法的MethodMetaData时,我们会找到RequestMapping注释以及Products和value参数,但是method字段始终是空数组,尽管我们在源代码中配置了它,并且映射工作正常。所以信息应该在某个地方。这真令人费解!:-)

编辑:方法字段为空=>RequestMapping注释有一个方法字段,它是RequestMethod对象的数组。如果您试图从MethodMetaData实例中读取它,它将是一个空数组。示例:metadata.getAnnotationAttributes(RequestMapping.class.getName()).get(“方法”)

我试图在spring框架源代码中找到原因,但到目前为止还没有找到原因

有什么想法吗


仅供参考:我们使用的是Spring 3.1,出于好奇,我创建了一个小样本项目,并对Spring提供的MetadataReader进行了一些修改。对于演示,我创建了一个非常简单的控制器,如下所示:

@Controller
public class SomeAnnotatedController {

   @RequestMapping(method = {RequestMethod.GET}, value = "/someUrl")
   public void someMethod() {
       // do something later
   }

}
@Controller
public class EndpointDocController {

    private final RequestMappingHandlerMapping handlerMapping;

    @Autowired
    public EndpointDocController(RequestMappingHandlerMapping handlerMapping) {
        this.handlerMapping = handlerMapping;
    }

    @RequestMapping(value="/endpointdoc", method=RequestMethod.GET)
    public void show(Model model) {
        model.addAttribute("handlerMethods", this.handlerMapping.getHandlerMethods());
    }

}
我无法使用Spring MetadataReader从注释中提取正确的信息

@Test
public void shouldReturnMethodArrayWithSpringMetadataReader() throws Exception {
    MetadataReader metadataReader = new CachingMetadataReaderFactory().getMetadataReader(SomeAnnotatedController.class.getName());
    Set<MethodMetadata> annotatedMethods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(RequestMapping.class.getName());
    assertEquals(1, annotatedMethods.size());
    MethodMetadata methodMetadata = annotatedMethods.iterator().next();
    assertEquals("someMethod", methodMetadata.getMethodName());
    Map<String, Object> annotationAttributes = methodMetadata.getAnnotationAttributes(RequestMapping.class.getName());
    assertTrue(annotationAttributes.containsKey("method"));
    RequestMethod[] methodAttribute = (RequestMethod[]) annotationAttributes.get("method");
    assertEquals(1, methodAttribute.length);
}
使用本机Java执行同样的操作感觉稍微容易一些,并返回正确的信息

@Test
public void shouldReturnMethodArrayWithPlainJava() throws Exception {
    Method method = SomeAnnotatedController.class.getDeclaredMethod("someMethod");
    RequestMapping annotation = method.getAnnotation(RequestMapping.class);
    assertEquals(1, annotation.method().length);
    assertEquals(RequestMethod.GET, annotation.method()[0]);
}

因此,我很抱歉地告诉您,我没有找到问题的解决方案,但基于纯java的示例项目或文档化的替代方案可能会有所帮助。

这不是对您所要求的内容的直接回答,而是对REST API进行自文档化的一种非常好的方法。使用Rossen Stoyanchev在其github位置描述的端点文档控制器:

总而言之,控制器的外观如下所示:

@Controller
public class SomeAnnotatedController {

   @RequestMapping(method = {RequestMethod.GET}, value = "/someUrl")
   public void someMethod() {
       // do something later
   }

}
@Controller
public class EndpointDocController {

    private final RequestMappingHandlerMapping handlerMapping;

    @Autowired
    public EndpointDocController(RequestMappingHandlerMapping handlerMapping) {
        this.handlerMapping = handlerMapping;
    }

    @RequestMapping(value="/endpointdoc", method=RequestMethod.GET)
    public void show(Model model) {
        model.addAttribute("handlerMethods", this.handlerMapping.getHandlerMethods());
    }

}
假设hm是一个处理程序方法,您的jsp将以这种方式引用方法、生成、使用、方法签名的属性:

Patterns:${hm.key.patternsCondition.patterns}
Method: ${hm.key.methodsCondition.methods}
Method signature: ${hm.value}
Consumes: ${hm.key.consumesCondition.expressions}
Produces: ${hm.key.producesCondition.expressions}

但是方法字段总是空的??描述请查看编辑部分我不知道MetadataReader的工作(编码),检查是否有其他方法检索对象信息,因为@RequestMapping注释中的方法属性类型是RequestMethod数组。i、 我已经澄清了这一点。当然,它是一个空数组,而不是一个空变量。我的错。MetadataReader是一个spring类。看起来就像我需要的一样-你介意我问你在哪里实例化RequestMappingHandlerMapping吗?我看到的所有示例都只是使用默认构造函数实例化它,但它随后返回并清空处理程序方法的映射:(