Изменение в элементах Json, приводящее к ошибке в коде - PullRequest
1 голос
/ 11 апреля 2019

Я наконец-то получил свой код для начала синтаксического анализа, но кажется, что когда я достигаю определенных частей 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

1 Ответ

0 голосов
/ 11 апреля 2019

Этот JSON ... неудачный.Вы можете создать JsonDeserializer клиента, но он все равно должен вернуть что-то для филиалов.

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]]

При этом ваш список филиалов имеет нулевое значение, а этоплохо, но шаг в правильном направлении - вы можете очистить их после десериализации.

...