【问题标题】:Genson with Jersey JsonBindingException: Could not deserialize to type class java.lang.StringGenson with Jersey JsonBindingException:无法反序列化为类 java.lang.String
【发布时间】:2015-01-20 08:17:21
【问题描述】:

在我的 Spring MVC Java 应用程序中,我使用 Jersey REST API。我正在使用杰克逊进行 JSON 处理。我将 Genson 添加到我的项目中,用于过滤某些类的某些字段。我试图只为此使用 Genson,剩下的我想使用 Jackson。

但是当 Jar 位于类路径 (Got to know from this link) 中时,默认情况下使用 Jersey REST api 作为启用 Jersey 的 Genson 时出现异常。

这是我连接到 Web 服务并使用 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;
}

我收到以下异常

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 或如何使用 Genson 解决此问题?

谢谢

【问题讨论】:

  • 如果您对始终使用 genson 没问题,那么您可以直接选择您想要的类型,而不是将响应作为字符串获取。
  • 我想要它作为字符串。我怎样才能得到它?
  • 如果您仍然需要在 Jax-RS 中禁用 Genson,新版本包含此机制,请参阅我的更新。

标签: java jersey jersey-client genson


【解决方案1】:

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

实际发生的情况

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

当您执行 getEntity(String.class) 时,Jersey 要求 Genson 将传入的 json 转换为字符串。请注意,一般 json 格式不允许字符串作为根值。

解决方案

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

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

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


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

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

【讨论】:

  • 我只使用杰克逊。但在某些情况下,我需要在序列化时从 POJO 中删除字段。与 Jackson 比较复杂,因为需要添加@JsonFilter 注解。如果注释存在于 POJO 类中,则在使用 Jackson 以正常方式序列化时会出现问题。所以我正在使用Genson。但我直接使用而不是与泽西岛一起使用。
  • 还有哪些您在 Jackson 中使用但在 Genson 中不存在的功能?我建议您选择解决方案 1,如果它涵盖您的用例,则只保留一个库。 Genson 的下一个版本将包括一个在 jax rs 应用程序中禁用它的系统。
  • 我正在尝试使用 Genson 并删除 Jackson。谢谢:)
  • Use getEntityInputStream method from ClientResponse to get the raw InputStream and convert it to a String. 在无望地寻找错误的几个小时后,这救了我。谢谢!
【解决方案2】:

这是解决方案 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;
    }
}

【讨论】:

    猜你喜欢
    • 2018-03-25
    • 2021-10-27
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 2012-11-18
    • 1970-01-01
    相关资源
    最近更新 更多