WebClient getCollection() doesn't work with Jackson's JSON Provider because it
passes the wrong types to readFrom()
-------------------------------------------------------------------------------------------------------------------
Key: CXF-3149
URL: https://issues.apache.org/jira/browse/CXF-3149
Project: CXF
Issue Type: Bug
Reporter: Dobes Vandermeer
When you request a collection from the WebClient it calls readFrom() using the
type == Collection.class and the genericType == the member type of the class.
Unfortunately, this isn't what is normally passed as the genericType when
reflection or a GenericEntity was used to write out an object. Normally, the
genericType == Collection<X>. In order to be more compatible with third-party
providers, it would be best if the generic type was set consistently in each
case, rather than having a special case for the collections.
To support this, the genericType should be set to a subclass of
ParameterizedType, for example an instance of this class:
{code}
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
public final class ParameterizedCollectionType<T> implements ParameterizedType {
private final Class<T> collectionMemberClass;
private final Type[] typeArgs;
public ParameterizedCollectionType(Class<T> collectionMemberClass) {
this.collectionMemberClass=collectionMemberClass;
this.typeArgs=new Type[] { collectionMemberClass };
}
public Type[] getActualTypeArguments() {
return typeArgs;
}
public Type getOwnerType() {
return null;
}
public Type getRawType() {
return Collection.class;
}
public String toString() {
return
"java.util.Collection<"+collectionMemberClass.getName()+">";
}
}
{code}
If this class was used in
org.apache.cxf.jaxrs.client.WebClient.invokeAndGetCollection(String, Object,
Class<T>) then the client would be able to read a JSON collection response
using the JacksonJsonProvider.
As a workaround I have created a subclass of JacksonJsonProvider that "fixes"
this issue by overriding readFrom():
{code}
/**
* For collections, CXF passes type == Collection.class and genericType
== the member class type.
*
* But actually, it should pass genericType = Collection<X> as the
generic type in order for Jackson
* to understand it.
*/
@SuppressWarnings("unchecked")
@Override
public Object readFrom(Class<Object> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream
entityStream) throws IOException {
if(type.equals(Collection.class) && !(genericType instanceof
ParameterizedType)) {
genericType = new
ParameterizedCollectionType<Object>((Class)genericType);
}
return super.readFrom(type, genericType, annotations,
mediaType, httpHeaders, entityStream);
}
{code}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.