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