【问题标题】:Change in Json Elements causing error in codeJson 元素的更改导致代码错误
【发布时间】:2019-04-11 00:02:49
【问题描述】:

我终于可以开始解析我的代码了,但是当我到达 Json 的某些部分时,它似乎会抛出错误。由于某种原因,Json 中的某些元素与名称相似的元素不同。我正在使用的 API:http://api.nobelprize.org/v1/laureate.json?

例如:普通元素

"year": "someYear",
 "category": "someCategory",
"share": "someint",
"motivation": "\"someMotivation\"",
"affiliations": [
                 {
                  "name": "SomeName",
                  "city": "someCity",
                  "country": "SomeCountry"
                 }
                ]

json 字符串后面的元素导致错误

"year": "someYear",
 "category": "someCategory",
"share": "someint",
"motivation": "\"someMotivation\"",
"affiliations": [
                  []
                ]

由于某种原因,API 在导致错误的 affiliations 元素中放置了一个空列表。

我目前的隶属关系类如下所示:

public class Affiliations {
    String name;
    String city;
    String country;
}

我得到的错误:

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY

【问题讨论】:

  • 他们的 API 非常糟糕,除非affiliations 中的空数组有什么特殊含义。你需要一个自定义的反序列化器。
  • 不幸的是,我一直坚持使用它,而且我认为没有任何理由包含一个空数组而不是 null。但正因为如此,它破坏了我的代码。你知道我将如何为它编写反序列化器吗?

标签: java parsing gson


【解决方案1】:

那个 JSON 是……不幸的。您可以创建一个客户 JsonDeserializer,但它仍然必须为 Affiliations 返回 something

class Main {
    public static void main(String[] args) {
        final String json = "{ \"name\": \"William Shakespeare\", \"affiliations\": [ { \"name\": \"Globe Theatre\" }, [] ] }";
        final Gson gson = new GsonBuilder()
                .registerTypeAdapter(Affiliation.class, new AffiliationDeserializer())
                .create();
        final Laureate laureate = gson.fromJson(json, Laureate.class);
        System.out.println(laureate);

    }

    private static class Laureate {
        String name;
        List<Affiliation> affiliations;

        public Laureate(final String name) {
            this.name = name;
        }

        public String toString() {
            return "Laureate[name=" + name + ", affiliations=" + affiliations + "]";
        }
    }

    private static class Affiliation {
        String name;

        public String toString() {
            return "Affiliation[name=" + name +"]";
        }
    }

    private static class AffiliationDeserializer implements JsonDeserializer<Affiliation> {
        // this innerGson doesn't have AffiliationDeserializer registered, 
        // so it won't get stuck in an infinite loop
        private static final Gson innerGson = new Gson();

        @Override
        public Affiliation deserialize(final JsonElement json, final Type typeOfT,
                                       final JsonDeserializationContext context)
        throws JsonParseException {
            if (json.isJsonObject()) {
                return innerGson.fromJson(json, Affiliation.class);
            } else {
                return null;
            }
        }
    }
}
Laureate[name=William Shakespeare, affiliations=[Affiliation[name=Globe Theatre], null]]

这样,您的从属关系列表中有一个空值,这很糟糕,但这是朝着正确方向迈出的一步 - 您可以在反序列化后清理这些。

【讨论】:

  • 这很可能会解决我的问题,但由于某种原因,在实现和覆盖反序列化器时我总是会出错。我似乎得到了这个错误:@Override 上的AffiliationDeserializer is not abstract and does not override abstract method deserialize(JsonElement,Type,JsonDeserializationContext) in JsonDeserializermethod does not override or implement a method from a supertype
  • 刚刚修复它,似乎我自动导入了一些不断破坏它的东西。这是正确的导入 import com.google.gson.Gson; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import java.lang.reflect.Type; 和给我错误 import java.lang.ProcessBuilder.Redirect.Type; 的导入
猜你喜欢
  • 2017-08-09
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 1970-01-01
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多