亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將 Json 數組映射到 Java 模型

將 Json 數組映射到 Java 模型

慕婉清6462132 2022-08-03 10:46:05
我有一個復雜的json,就像在這里一樣我正在嘗試在我的模型類“ChromeJsonModel”中映射它,例如:Type collectionType = new TypeToken<List<ChromeJsonModel>>(){}.getType(); List<ChromeJsonModel> jsonModelList = (List<ChromeJsonModel>) new Gson().fromJson( jsonPrettyPrintString , collectionType);Bu t 我收到以下錯誤。Expected BEGIN_ARRAY but was BEGIN_OBJECT我為什么以及哪里出錯的原因是什么?
查看完整描述

3 回答

?
慕運維8079593

TA貢獻1876條經驗 獲得超5個贊

您有非常復雜的有效負載,其中同一屬性可以有一個或一個對象。 默認情況下不處理這種情況,我們需要為此類屬性實現自定義 deserialiser。下面我創建了表示您的有效負載的簡單模型:JSONJSON objectJSON arrayGsonone-or-manyPOJOJSON


class TestResponse {


    @SerializedName("test-run")

    private TestRun testRun;


    // other properties, getters, setters, toString

}


class TestRun {


    @SerializedName("test-suite")

    private List<TestSuite> testSuite;


    // other properties, getters, setters, toString

}


class TestSuite {

    private String result;

    private double duration;


    @SerializedName("test-suite")

    private List<TestSuite> testSuites;


    @SerializedName("test-case")

    private List<TestCase> testCases;


    // other properties, getters, setters, toString

}


class TestCase {


    private String fullname;


    // other properties, getters, setters, toString

}

如您所見,是 -es 屬性。讓我們為這些屬性實現自定義 deserialiser:test-suitetest-caseList


class OneOrManyJsonDeserializer<E> implements JsonDeserializer<List<E>> {


    private final Class<E> clazz;


    public OneOrManyJsonDeserializer(Class<E> clazz) {

        this.clazz = clazz;

    }


    @Override

    public List<E> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

        if (json instanceof JsonArray) {

            final JsonArray array = (JsonArray) json;

            final int size = array.size();

            if (size == 0) {

                return Collections.emptyList();

            }

            final List<E> suites = new ArrayList<>(size);

            for (int i = 0; i < size; i++) {

                suites.add(context.deserialize(array.get(i), clazz));

            }


            return suites;

        }


        E suite = context.deserialize(json, clazz);

        return Collections.singletonList(suite);

    }

}

Class<E>在運行時需要正確反序列化給定 。之后,讓我們創建并自定義實例:JSON objectGson


import com.google.gson.Gson;

import com.google.gson.GsonBuilder;

import com.google.gson.JsonArray;

import com.google.gson.JsonDeserializationContext;

import com.google.gson.JsonDeserializer;

import com.google.gson.JsonElement;

import com.google.gson.JsonParseException;

import com.google.gson.annotations.SerializedName;

import com.google.gson.reflect.TypeToken;


import java.io.File;

import java.io.FileReader;

import java.lang.reflect.Type;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;


public class GsonApp {


    public static void main(String[] args) throws Exception {

        File jsonFile = new File("./resource/test.json").getAbsoluteFile();


        Type testCaseListType = new TypeToken<List<TestCase>>() {}.getType();

        Type testSuiteListType = new TypeToken<List<TestSuite>>() {}.getType();

        Gson gson = new GsonBuilder()

                .registerTypeAdapter(testCaseListType, new OneOrManyJsonDeserializer<>(TestCase.class))

                .registerTypeAdapter(testSuiteListType, new OneOrManyJsonDeserializer<>(TestSuite.class))

                .setPrettyPrinting()

                .create();


        TestResponse response = gson.fromJson(new FileReader(jsonFile), TestResponse.class);

        System.out.println(response);

    }

}

如您所見,我們為每種類型的注冊了兩個實例。我們需要使用來正確映射我們的實例。one-to-manyTypeToken

版本 2

在玩了上面的解決方案之后,我想出了下面的deserialiser:


class OneOrManyJsonDeserializer implements JsonDeserializer<List<?>> {


    @Override

    public List<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

        final Type elementType = $Gson$Types.getCollectionElementType(typeOfT, List.class);


        if (json instanceof JsonArray) {

            final JsonArray array = (JsonArray) json;

            final int size = array.size();

            if (size == 0) {

                return Collections.emptyList();

            }


            final List<?> suites = new ArrayList<>(size);

            for (int i = 0; i < size; i++) {

                suites.add(context.deserialize(array.get(i), elementType));

            }


            return suites;

        }


        Object suite = context.deserialize(json, elementType);

        return Collections.singletonList(suite);

    }

}

我們不需要定制它。使用類,我們可以獲得元素的類型并反序列化內部元素。簡單用法:$Gson$Types


import com.google.gson.Gson;

import com.google.gson.GsonBuilder;

import com.google.gson.JsonArray;

import com.google.gson.JsonDeserializationContext;

import com.google.gson.JsonDeserializer;

import com.google.gson.JsonElement;

import com.google.gson.JsonParseException;

import com.google.gson.annotations.SerializedName;

import com.google.gson.internal.$Gson$Types;


import java.io.File;

import java.io.FileReader;

import java.lang.reflect.Type;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;


public class GsonApp {


    public static void main(String[] args) throws Exception {

        File jsonFile = new File("./resource/test.json").getAbsoluteFile();


        Gson gson = new GsonBuilder()

                .registerTypeAdapter(List.class, new OneOrManyJsonDeserializer())

                .setPrettyPrinting()

                .create();


        TestResponse response = gson.fromJson(new FileReader(jsonFile), TestResponse.class);

        System.out.println(response);

    }

}

上面的代碼也應該適合你。


查看完整回答
反對 回復 2022-08-03
?
森欄

TA貢獻1810條經驗 獲得超5個贊

我認為你可以使用杰克遜。

ObjectMapper mapper = new ObjectMapper();
List<ChromeJsonModel> participantJsonList = mapper.readValue(jsonString, new TypeReference<List<ChromeJsonModel>>(){});


查看完整回答
反對 回復 2022-08-03
?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

在你的根元素是 json 對象:json


{    <---- HERE YOU HAVE "OBJECT"


  "test-run": {

    "duration": 508.56199999999995,

    "result": "Passed",

    ...

   }


}

改變:


List<ChromeJsonModel> jsonModelList = (List<ChromeJsonModel>) ... ;

自:


ChromeJsonModel jsonModelList = (ChromeJsonModel) ... ;

您可以嘗試在那里生成POJO:http://pojo.sodhanalibrary.com/


查看完整回答
反對 回復 2022-08-03
  • 3 回答
  • 0 關注
  • 169 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號