Genson with Jersey JsonBindingException:无法反序列化以输入类java.lang.String

时间:2015-01-20 08:17:21

标签: java jersey jersey-client genson

在我的Spring MVC Java应用程序中,我使用的是Jersey REST API。我正在使用Jackson进行JSON处理。我将 Genson 添加到我的项目中,以过滤某些类的某些字段。而我正试图仅仅使用Genson,剩下我想使用Jackson。

但是当我使用Jersey REST api时我得到了例外,因为当Jar在类路径(Got to know from this link)时,默认情况下Jersey启用了Genson。

以下是我连接到Web服务并获取数据并使用Jackson

转换为String的代码
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;
}

我得到了异常

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

第74行是指stringResponse = response.getEntity(String.class);

如何禁用Genson for Jersey或如何使用Genson解决此问题?

由于

2 个答案:

答案 0 :(得分:3)

Genson的最新文档托管在github http://owlike.github.io/genson/上。

实际发生的事情

对我来说,目前尚不清楚你想在哪里使用Genson以及如何使用。您是否仅使用Genson进行序列化?你是通过运动衫还是直接使用它?

当你执行getEntity(String.class)时,Jersey会要求Genson将传入的json设置为字符串。请注意,通常json格式不允许字符串作为根值。

<强>解决方案

  1. 升级到泽西2.X(和最新的Genson版本),在新泽西版本中,当您将输入作为字符串询问时,它不会委托给MessageBodyReader(正确的行为IMO)。然后你可以使用这个字符串来设置你想要的任何类型。

  2. 使用ClientResponse中的getEntityInputStream方法获取原始InputStream并将其转换为String。

  3. 另一个解决方案是覆盖Gensons的MessageBodyReader实现,不处理对String的deser。


  4. 有多个同时处理JSON转换的库对我来说听起来不对。尤其是(Jackson和Genson)都提供了一些类似的功能。我打开了an issue,允许人们在JAX-RS应用程序中禁用Genson。

    更新 Genson 1.3及更高版本为disable Genson in a Jax-RS应用提供系统。

答案 1 :(得分:0)

这是解决方案2的示例...

使用ClientResponse中的getEntityInputStream方法获取原始InputStream并将其转换为字符串:

private String responseString(ClientResponse response) {
    InputStream stream = response.getEntityInputStream();
    StringBuilder textBuilder = new StringBuilder();
    try (Reader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName(StandardCharsets.UTF_8.name())))) {
        int c = 0;
        while ((c = reader.read()) != -1) {
            textBuilder.append((char) c);
        }
        return textBuilder.toString();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}