2012-04-24 2 views
1

私たちは、何らかの自動自己記述RESTサービス(ライブドキュメント生成)を構築しています。このために、すべてのコントローラーBeanを検索し、要求マッピング情報を取り出して親しみやすいhtmlページに表示するコントローラーメソッドがあります。RequestMappingアノテーションは、コントローラメソッドのアノテーションを参照するときに空のRequestMethod配列につながります

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

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

私は春のフレームワークのソースコードで理由を見つけようとしましたが、これまでの理由は見つかりませんでした...

アイデア? FYI

:私たちは

+1

ただし、メソッドフィールドは常に空ですか?記述する –

+0

編集部分を参照してください –

+0

@RequestMappingアノテーションのメソッド属性の型がRequestMethodの配列であるため、MetadataReaderの作業(コーディング)がわからない場合、オブジェクト情報を取得する方法が他にあるかどうかを確認してください。すなわちRequestMethod [] –

答えて

1

春3.1を使っているが、私は自分の好奇心から少しサンプルプロジェクトを作成し、春が提供するMetadataReaderを少しいじっ。

@Controller 
public class SomeAnnotatedController { 

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

} 

私は春MetadataReaderを使用して注釈から正しい情報を抽出することができませんでした。デモのために私はこのように見えた非常に単純なコントローラを作成しました。ネイティブJavaで同じことを

@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 

は少し簡単に感じているし、正しい情報を返します。 。

@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に基づいて文書の代替が役立つかもしれないということを教えてくれて申し訳ありません。

+0

ありがとう!私は、プレーンJavaを使用するコードをリファクタリングすると思います。 –

1

これはあなたの質問に対する直接の回答ではありませんが、REST APIの自己文書化を行うための非常に良い方法です。生産、

@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は、メソッドの属性を参照します:あなたのコントローラは次のようになり、要約するhttps://github.com/rstoyanchev/spring-mvc-31-demo.git

:彼のgithubの場所で、ここロッセンStoyanchevで説明エンドポイントのドキュメントコントローラを使用します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} 
+0

私が必要とするもののように見えます。RequestMappingHandlerMappingをどこでインスタンス化すればいいですか?すべての例では、デフォルトのコンストラクタでインスタンス化するだけですが、ハンドラメソッドのマップを返して空にします。 – Adam

関連する問題