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.

Reply via email to