2011-08-12 21 views
16

Jerseyのジェネリック関数を作成しようとしていますが、これはRESTを通じて同じタイプのオブジェクトのリストを取得するために使用できます。しかし、これは動作していないlinkリストとしてのRESTリソースの取得

@Override 
public <T> List<T> fetchResourceAsList(String url) { 
    ClientConfig cc = new DefaultClientConfig(); 
    Client c = Client.create(cc); 
    if (userName!=null && password!=null) { 
    c.addFilter(new HTTPBasicAuthFilter(userName, password)); 
    } 
    WebResource resource = c.resource(url); 
    return resource.get(new GenericType<List<T>>() {}); 
} 

:私はこのフォーラムで見つかった情報に基づいて、それを。私がそれを実行しようとすると、私は次のエラーが発生します:SEVERE: A message body reader for Java class java.util.List, and Java type java.util.List<T>, and MIME media type application/xml was not found

しかし、テンプレートを使わずにこの関数を書くと(実際のクラス名でTを置き換えると)うまくいくだけです。もちろん、このようにして関数は意味を失います。

これを修正する方法はありますか? Unmarshallerのは、それが返されたコンテンツをunmarhallできる前にそこにあるどのようなタイプのオブジェクトを知る必要があり

同様にあなたを助けるかもしれジャージの

+0

リンク http://stackoverflow.com/questions/1603404/using-jaxb-to-unmarshal-marshal-a-liststring – fmucar

+0

@fmucar以下を参照:これは再びとして、サーバーのためのヒントを持っていますそうですか。私は、クライアントのためのジェネリックタイプのサポートが必要です。 – NagyI

答えて

21

私が見つけた解決策 https://java.net/projects/jersey/lists/users/archive/2011-08/message/37

public <T> List<T> getAll(final Class<T> clazz) { 

    ParameterizedType parameterizedGenericType = new ParameterizedType() { 
     public Type[] getActualTypeArguments() { 
      return new Type[] { clazz }; 
     } 

     public Type getRawType() { 
      return List.class; 
     } 

     public Type getOwnerType() { 
      return List.class; 
     } 
    }; 

    GenericType<List<T>> genericType = new GenericType<List<T>>(
      parameterizedGenericType) { 
    }; 

    return service.path(Path.ROOT).path(clazz.getSimpleName()) 
      .accept(MediaType.APPLICATION_XML).get(genericType); 
} 
+0

これはJersey 2.9で私の仕事をしてくれました。ありがとうございました! –

+0

BTW、あなたの例では拡張し、OwnerTypeとRawTypeの基本クラスCollection.classを使用しました。だから私は、すべてのコレクション型に単一のparameterizedTypeを再利用できるはずです。 –

6

参照GenericTypeクラス。ジェネリックスの情報は実行時に利用できないため、あなたが求めているものは不可能です。それは、それが何も知らない何かを非難する。

あなたができることは最高です。

public <T> List<T> fetchResourceAsList(Class<?> beanClass, String url) { 
    ... 

    if(beanCLass.equals(MyBean.class)){ 
     return resource.get(new GenericType<List<MyBean>>() 
    }else if(...){ 
     ... 
    }... 
} 

やジェネリック医薬品の警告と

(これが動作する場合、私はわからない)

public List fetchResourceAsList(String url) { 
    ... 
     return resource.get(new GenericType<List<Serializable>>() 
} 
+0

サーバー側のサンプルを提供しました。これはどのようにクライアント側で私を助けることができますか? Jerseyサーバーによって生成されたリストをブラウザーで表示できます。私の問題は、上記の関数でgeneric型を使用している場合、クライアントがリソースをフェッチできないことです。特定のタイプのために毎回手動でクライアントを構築すると、リソースを取得できます。しかし、私はこれを望んでいません。 – NagyI

+0

私は得ました。それはここで説明したのと同じ問題です:http://janmaterne.wordpress.com/2008/10/10/getting-the-type-of-a-generic-class-at-runtime/ – NagyI

+0

私はジェネリックス情報isn実行時に利用できませんか? – gosua

3

user2323189に拡張すると、あなたは、コレクションを使用することができますList.classの代わりに、Collectionを拡張するすべての型を直列化できるようにします。私は基本クライアントクラスで単純なゲッターを作成し、これを使って任意のタイプのコレクションを取得することができます。私のコンストラクタで提供されているclazz変数は提供されていないので、提供された引数ではありません。おそらくこれを静的メソッドに変えて、GenericType>というシグネチャをClassのパラメータとともに使用して、より一般的なものにすることができます。

public GenericType<Collection<T>> getParameterizedCollectionType() { 
     ParameterizedType parameterizedGenericType = new ParameterizedType() { 
      public Type[] getActualTypeArguments() { 
       return new Type[] { clazz }; 
      } 

      public Type getRawType() { 
       return Collection.class; 
      } 

      public Type getOwnerType() { 
       return Collection.class; 
      } 
     }; 
     return new GenericType<Collection<T>>(parameterizedGenericType){}; 
    } 
関連する問題