【问题标题】:Problem deserializing Bugzilla JSON using Google's Gson使用 Google 的 Gson 反序列化 Bugzilla JSON 的问题
【发布时间】:2011-01-03 16:28:36
【问题描述】:

我在从 Bugzilla 服务器返回的 JSON 中遇到问题,因为它有时会返回“text”:{},有时会返回“text”:“blah blah blah”。如果没有给出错误描述,Bugzilla 会返回前者。我很困惑为什么它没有像更明智的“文本”一样回来:“”但确实如此,就是这样。

如果我在 Gson 的目标对象中有一个名为 text 的字符串,当它看到 {} 情况时它会反对,因为它说这是一个对象而不是字符串:

Exception in thread "main" com.google.gson.JsonParseException: The 
JsonDeserializer StringTypeAdapter failed to deserialized json object {} given 
the type class java.lang.String

关于如何让 Gson 解析这个有什么建议吗?

【问题讨论】:

  • 您在 Bugzilla 中使用什么 JSON 接口?我是 JSON-RPC 接口的作者,我无法想象会发生什么情况。如果这是 REST API,那就另当别论了——这是一个单独维护的独立产品。
  • 这是我正在使用的 REST API。

标签: java json gson


【解决方案1】:

Gson 需要针对原始问题中的情况进行自定义反序列化。以下是一个这样的例子。

input.json:

[
  {
    "text":"some text"
  },
  {
    "text":{}
  }
]

Foo.java:

import java.io.FileReader;
import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(String.class, new StringDeserializer());
    Gson gson = gsonBuilder.create();
    Thing[] things = gson.fromJson(new FileReader("input.json"), Thing[].class);
    System.out.println(gson.toJson(things));
  }
}

class Thing
{
  String text;
}

class StringDeserializer implements JsonDeserializer<String>
{
  @Override
  public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException
  {
    if (json.isJsonPrimitive()) return json.getAsString();
    return "";
  }
}

输出:

[{"text":"some text"},{"text":""}]

使用 Thing.class 类型的自定义反序列化器当然是可能的。这样做的好处是不会为每个String 添加额外的处理,但是你会被“手动”处理Thing 的所有其他属性所困。

【讨论】:

    【解决方案2】:

    尝试将text 字段声明为Object。然后执行以下操作:

    public String getTextAsString() {
        if (text instanceof String) {
            return (String) text;
        else {
            return null;
        }
    }
    

    您应该将此作为错误报告给 Bugzilla 项目。这种行为没有充分的理由。

    【讨论】:

    • 如果 "text" 被声明为 Object 类型,那么 Gson 仍然卡在 "text":{} 上,抱怨“类型信息不可用,并且目标对象不是原始对象:{} "。
    猜你喜欢
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多