Genson with Jersey JsonBindingException: Could not deserialize to type class java.lang.String

iCode picture iCode · Jan 20, 2015 · Viewed 9k times · Source

In my Spring MVC Java application I'm using Jersey REST API. I am using Jackson for JSON processing. I added Genson to my project for filtering some fields for some classes. And I am trying to use Genson only for that and remaining I want to use Jackson.

But I am getting exception while using Jersey REST api as Jersey enabled Genson by default when the Jar is in the classpath (Got to know from this link).

Here is my code in connect to web service and get data and convert to String using Jackson

public String connect() throws Exception {
        Client client = Client.create();
        try {
            String auth = new String(Base64.encode(userName + COLON + password));
            WebResource webResource = client
                    .resource(webServiceUrl);
            ClientResponse response = webResource
                    .header(AUTHORIZATION, BASIC + auth).type(APPLICATION_JSON)
                    .accept(APPLICATION_JSON).get(ClientResponse.class);
            //code to check response status code.
                stringResponse = response.getEntity(String.class);

        } catch (ClientHandlerException e) {
            throw new Exception("Not a Valid Url.");
        } finally {
            client.destroy();
        }
        return stringResponse;
}

I'm getting following exception

javax.ws.rs.WebApplicationException: com.owlike.genson.JsonBindingException: Could not deserialize to type class java.lang.String
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:130)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:553)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)
    at com.myapp.WebHttpClient.connect(WebHttpClient.java:74)
    at com.myapp.connection.connectors.WebConnector.getData(WebConnector.java:39)
    at com.myapp.adapter.impl.SourceAdapter.getData(SourceAdapter.java:29)
    at com.myapp.service.impl.WebServiceImpl.adapter(WebServiceImpl.java:174)
    at com.myapp.service.impl.WebServiceImpl.connect(WebServiceImpl.java:107)
    ... 41 more
Caused by: com.owlike.genson.JsonBindingException: Could not deserialize to type class java.lang.String
    at com.owlike.genson.Genson.deserialize(Genson.java:398)
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:128)
    ... 48 more
Caused by: com.owlike.genson.stream.JsonStreamException: Readen value can not be converted to String
    at com.owlike.genson.stream.JsonReader.valueAsString(JsonReader.java:200)
    at com.owlike.genson.convert.DefaultConverters$StringConverter.deserialize(DefaultConverters.java:364)
    at com.owlike.genson.convert.DefaultConverters$StringConverter.deserialize(DefaultConverters.java:351)
    at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:56)
    at com.owlike.genson.Genson.deserialize(Genson.java:396)
    ... 49 more

Line 74 refers to stringResponse = response.getEntity(String.class);.

How to disable Genson for Jersey or How can I resolve this issue by using Genson?

Thanks

Answer

eugen picture eugen · Jan 21, 2015

The up to date documentation of Genson is hosted on github http://owlike.github.io/genson/.

What actually happens

To me it is not clear where you want to use Genson and how. Are you using Genson for serialization only? Are you using it through jersey or directly?

When you do getEntity(String.class), Jersey asks Genson to deser the incoming json to a string. Note that in general json format does not allow strings as root values.

Solutions

  1. Upgrade to jersey 2.X (and latest Genson release), in the new Jersey version when you ask the input as a string it does not delegate to MessageBodyReader (correct behaviour IMO). Then you can use this string to deser to whatever type you want.

  2. Use getEntityInputStream method from ClientResponse to get the raw InputStream and convert it to a String.

  3. Another solution would be to override Gensons implementation of MessageBodyReader, to not handle deser to String.


Having multiple libs that handle JSON conversion at the same time does not sound right to me. Especially as both (Jackson and Genson) provide some similar features. I opened an issue allowing people to disable Genson in JAX-RS apps.

Update Genson 1.3 and up provide a system to disable Genson in a Jax-RS app.