1

ある種の自動自己記述型RESTサービス(ライブドキュメント生成)を構築しています。このために、すべてのコントローラーBeanを検索し、リクエストマッピング情報もフェッチして、わかりやすいhtmlページに表示するコントローラーメソッドがあります。

このために、MetadataReader(CachingMetadataReaderFactoryを介して作成された)を使用して、クラスのメタデータをフェッチします。パブリックメソッドのMethodMetaDataを取得すると、ProductsパラメーターとvalueパラメーターとともにRequestMappingアノテーションが見つかりますが、メソッドフィールドは常に空の配列ですが、ソースコードで構成されており、マッピングは機能します。したがって、情報はどこかにあるはずです。これはかなり不可解です!:-)

編集:メソッドフィールドは空です=> RequestMappingアノテーションには、RequestMethodオブジェクトの配列であるメソッドフィールドがあります。MethodMetaDataインスタンスからそれを読み取ろうとすると、空の配列になります。例:metadata.getAnnotationAttributes(RequestMapping.class.getName())。get( "method")

Spring Frameworkのソースコードで理由を見つけようとしましたが、今のところ理由がわかりません...

何か案は?

参考:Spring3.1を使用しています

4

2 に答える 2

1

私は自分の好奇心から小さ​​なサンプルプロジェクトを作成し、Springが提供するMetadataReaderを少しいじりました。デモでは、次のような非常に単純なコントローラーを作成しました。

@Controller
public class SomeAnnotatedController {

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

}

SpringMetadataReaderを使用して注釈から正しい情報を抽出できませんでした。

@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.lang.AssertionError: 
Expected :1
Actual   :0

ネイティブ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に基づく文書化された代替案が役立つ可能性があります。

于 2012-04-24T20:30:27.047 に答える
1

これはあなたが求めているものに対する直接の答えではありませんが、RESTAPIを自己文書化するための非常に良い方法です。Rossen Stoyanchevがgithubの場所で説明しているエンドポイントドキュメントコントローラーを使用します:https ://github.com/rstoyanchev/spring-mvc-31-demo.git

要約すると、コントローラーは次のようになります。

@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());
    }

}

そして、jspは、hmがハンドラーメソッドであると仮定して、この方法でメソッド、生成、消費、メソッドシグネチャの属性を参照します。

Patterns:${hm.key.patternsCondition.patterns}
Method: ${hm.key.methodsCondition.methods}
Method signature: ${hm.value}
Consumes: ${hm.key.consumesCondition.expressions}
Produces: ${hm.key.producesCondition.expressions}
于 2012-04-25T01:39:31.363 に答える