users@jersey.java.net

[Jersey] Jersey Client Jackson POJO mapping and generics issue

From: Noah White <emailnbw_at_gmail.com>
Date: Mon, 4 Jun 2012 15:51:25 -0400

I'm having a bit of an issue using Jersey client (1.11) with JSONConfiguration.FEATURE_POJO_MAPPING set to true. My test code looks like this:

MyFooCollectionWrapper<MyFooDTO> resp = webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType<MyFooCollectionWrapper<MyFooDTO>>() {});

On the server:

1) my web.xml has POJO Mapping set to true.

2) MyFooDTO is simply a POJO that looks like this:

public class MyFooDTO {

        private long id;
        private String propA;
        
        pubic long getId() {
                return id;
        }
        public void setId(long id) {
                this.id = id;
        }

        pubic String getPropA() {
                return propA;
        }
        public void setPropA(String propA) {
                this.propA = propA;
        }

        public MyFooDTO(MyFoo aFoo) {
                this.id = aFoo.getId();
                this.propA = aFoo.getPropA();
        }
}

3) MyFooCollectionWrapper looks like this:

        public class MyFooCollectionWrapper<T> extends MyFooCollectionWrapperBase {

                Collection<T> aCollection;

                public MyFooCollectionWrapper() {
                        super();
                }

                public MyFooCollectionWrapper(boolean isOK, String msg, Collection<T> col) {
                        super(isOK, msg);
                        this.aCollection = col;
                }

                public void setCollection(Collection<T> collection) {
                        this.aCollection = collection;
                }
        
                @JsonProperty("values")
                public Collection<T> getCollection() {
                        return aCollection;
                }
        }

        public class MyFooCollectionWrapperBase {

                private boolean isOK;
                private String message;

                public MyFooCollectionWrapperBase() {
                        this.message = "";
                        this.isOK = false;
                }

                public MyFooCollectionWrapperBase(boolean ok, String msg) {
                        this.isOK = ok;
                        this.message = msg;
                }

                .. standard getter/setters ..

        }

I've verified server has no problem creating the Json response. I can retrieve with my Jersey client code if I set the response type to String. When I use

MyFooCollectionWrapper<MyFooDTO> resp = webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType<MyFooCollectionWrapper<MyFooDTO>>() {});

I would expect POJO mapping to just work (marshall the response) without any need for a custom message body reader. However, I get:

Jun 04, 2012 3:02:20 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class com.foo.MyFooCollectionWrapper, and Java type com.foo. MyFooCollectionWrapper<com.foo. MyFooDTO>, and MIME media type application/json was not found
Jun 04, 2012 3:02:20 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
application/json ->
 com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
 com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App
 com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App
 com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
 com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
 com.sun.jersey.core.impl.provider.entity.FormProvider
 com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider
 com.sun.jersey.core.impl.provider.entity.StringProvider
 com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
 com.sun.jersey.core.impl.provider.entity.FileProvider
 com.sun.jersey.core.impl.provider.entity.InputStreamProvider
 com.sun.jersey.core.impl.provider.entity.DataSourceProvider
 com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
 com.sun.jersey.core.impl.provider.entity.ReaderProvider
 com.sun.jersey.core.impl.provider.entity.DocumentProvider
 com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
 com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
 com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
 com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
 com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$General
 com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$General
 com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
 com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
 com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
 com.sun.jersey.core.impl.provider.entity.EntityHolderReader
 com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
 com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
 com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy
 com.sun.jersey.moxy.MoxyMessageBodyWorker
 com.sun.jersey.moxy.MoxyListMessageBodyWorker


com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class com.foo.MyFooCollectionWrapper, and Java type com.foo. MyFooCollectionWrapper<com.foo. MyFooDTO>, and MIME media type application/json was not found
   at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:550)
   at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:524)
   at com.sun.jersey.api.client.WebResource.handle(WebResource.java:686)
   at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:74)
   at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:508)
        

The class path on the client side test includes:

jersey-test-framework-core-1.11.jar
jersey-test-framework-embedded-glassfish-1.11.jar
jersey-test-framework-grizzly-1.11.jar
jersey-test-framework-http-1.11.jar
jersey-test-framework-inmemory-1.11.jar
jackson-core-asl.jar
jackson-jaxrs.jar
jackson-xc.jar
jackson-client.jar
jersey-client.jar
jersey-core.jar
jersey-json.jar
jettison.jar

Are my expectations wrong or am I missing something obvious here?

Thanks,

-Noah