3

I have several client classes sending a list of beans via PUT method to a jersey webservice, so I have decided to refactor them into one class using generics. My first attempt was this:

public void sendAll(T list,String webresource) throws ClientHandlerException {
    WebResource ws = getWebResource(webresource);
    String response = ws.put(String.class, new GenericEntity<T>(list) {});
}

But when I called it with:

WsClient<List<SystemInfo>> genclient = new WsClient<List<SystemInfo>>();
genclient.sendAll(systemInfoList, "/services/systemInfo");

It gives me this error:

com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java type, class java.util.ArrayList, and MIME media type, application/xml, was not found

So I have tried taking out the method the GenericEntity declaration, and it works:

public void sendAll(T list,String webresource) throws ClientHandlerException {
 WebResource ws = ws = getWebResource(webresource);
 String response = ws.put(String.class, list);
}

Calling it with:

 WsClient<GenericEntity<List<SystemInfo>>> genclient = new WsClient<GenericEntity<List<SystemInfo>>>();
 GenericEntity<List<SystemInfo>> entity;
 entity = new GenericEntity<List<SystemInfo>>(systemInfoList) {};
 genclient.sendAll(entity, "/services/systemInfo");

So, why can't I generate a generic entity of a generic type inside the class, but doing it outside works?

4

1 に答える 1

1

クラス GenericEntity は、Java の型消去を回避するために使用されます。GenericEntity インスタンスの作成時に、Jersey は型情報を取得しようとします。

最初の例では、 GenericEntity コンストラクターはlisttype のパラメーターで呼び出さTれ、2 番目の例では、systemInfoListより適切な型情報を提供するように見えるパラメーターで呼び出されます。GenericEntity コンストラクターが内部で何をしているのかはわかりませんが、Java の型消去により、2 つのケースで異なるようです。

これらの解決策は一般的に機能しないため、型消去を回避しようとすることは決して賢明ではありません。これを試みたことでJerseyを責めることができます(またはタイプ消去のためにSun / Oracleを責めることができます)。

于 2012-05-22T16:14:16.963 に答える