[ 
https://issues.apache.org/jira/browse/CXF-3149?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Sergey Beryozkin resolved CXF-3149.
-----------------------------------

       Resolution: Fixed
    Fix Version/s: 2.4
                   2.3.1
         Assignee: Sergey Beryozkin

Brilliant, patch has been applied, thanks. 
Personally I'd expect 3rd party providers be more 'tolerant' (ex, CXF 
JAXBProvider works either way) but agree this fix is a useful one.

> 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
>          Components: JAX-RS
>    Affects Versions: 2.3.0
>            Reporter: Dobes Vandermeer
>            Assignee: Sergey Beryozkin
>             Fix For: 2.3.1, 2.4
>
>
> 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