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?
The class GenericEntity is used to go around the type erasure of Java. In the moment of creation of a GenericEntity instance Jersey tries to get the type information.
In the first example the GenericEntity constructor is called with the parameter
listof typeT, in the second example it is called with the parametersystemInfoList, which seem to provide better type information. I have no idea what the GenericEntity constructor is doing internally, but due to the type erasure of Java it seems to be different for the two cases.It is never wise to try to go around the type erasure, because these solutions don’t work generally. You can blame Jersey for trying this (or blame Sun/Oracle for the type erasure).