You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Dobes Vandermeer (JIRA)" <ji...@apache.org> on 2010/11/24 01:09:13 UTC

[jira] Updated: (CXF-3149) WebClient getCollection() doesn't work with Jackson's JSON Provider because it passes the wrong types to readFrom()

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

Dobes Vandermeer updated CXF-3149:
----------------------------------

          Component/s: JAX-RS
    Affects Version/s: 2.3.0

> 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
>
> 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.