猿问

将 Json 数组映射到 Java 模型

我有一个复杂的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

我为什么以及哪里出错的原因是什么?


慕婉清6462132
浏览 146回答 3
3回答

慕运维8079593

您有非常复杂的有效负载,其中同一属性可以有一个或一个对象。 默认情况下不处理这种情况,我们需要为此类属性实现自定义 deserialiser。下面我创建了表示您的有效负载的简单模型:JSONJSON objectJSON arrayGsonone-or-manyPOJOJSONclass TestResponse {&nbsp; &nbsp; @SerializedName("test-run")&nbsp; &nbsp; private TestRun testRun;&nbsp; &nbsp; // other properties, getters, setters, toString}class TestRun {&nbsp; &nbsp; @SerializedName("test-suite")&nbsp; &nbsp; private List<TestSuite> testSuite;&nbsp; &nbsp; // other properties, getters, setters, toString}class TestSuite {&nbsp; &nbsp; private String result;&nbsp; &nbsp; private double duration;&nbsp; &nbsp; @SerializedName("test-suite")&nbsp; &nbsp; private List<TestSuite> testSuites;&nbsp; &nbsp; @SerializedName("test-case")&nbsp; &nbsp; private List<TestCase> testCases;&nbsp; &nbsp; // other properties, getters, setters, toString}class TestCase {&nbsp; &nbsp; private String fullname;&nbsp; &nbsp; // other properties, getters, setters, toString}如您所见,是 -es 属性。让我们为这些属性实现自定义 deserialiser:test-suitetest-caseListclass OneOrManyJsonDeserializer<E> implements JsonDeserializer<List<E>> {&nbsp; &nbsp; private final Class<E> clazz;&nbsp; &nbsp; public OneOrManyJsonDeserializer(Class<E> clazz) {&nbsp; &nbsp; &nbsp; &nbsp; this.clazz = clazz;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public List<E> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {&nbsp; &nbsp; &nbsp; &nbsp; if (json instanceof JsonArray) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final JsonArray array = (JsonArray) json;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final int size = array.size();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (size == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Collections.emptyList();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final List<E> suites = new ArrayList<>(size);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < size; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; suites.add(context.deserialize(array.get(i), clazz));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return suites;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; E suite = context.deserialize(json, clazz);&nbsp; &nbsp; &nbsp; &nbsp; return Collections.singletonList(suite);&nbsp; &nbsp; }}Class<E>在运行时需要正确反序列化给定 。之后,让我们创建并自定义实例:JSON objectGsonimport 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 {&nbsp; &nbsp; public static void main(String[] args) throws Exception {&nbsp; &nbsp; &nbsp; &nbsp; File jsonFile = new File("./resource/test.json").getAbsoluteFile();&nbsp; &nbsp; &nbsp; &nbsp; Type testCaseListType = new TypeToken<List<TestCase>>() {}.getType();&nbsp; &nbsp; &nbsp; &nbsp; Type testSuiteListType = new TypeToken<List<TestSuite>>() {}.getType();&nbsp; &nbsp; &nbsp; &nbsp; Gson gson = new GsonBuilder()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .registerTypeAdapter(testCaseListType, new OneOrManyJsonDeserializer<>(TestCase.class))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .registerTypeAdapter(testSuiteListType, new OneOrManyJsonDeserializer<>(TestSuite.class))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .setPrettyPrinting()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .create();&nbsp; &nbsp; &nbsp; &nbsp; TestResponse response = gson.fromJson(new FileReader(jsonFile), TestResponse.class);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(response);&nbsp; &nbsp; }}如您所见,我们为每种类型的注册了两个实例。我们需要使用来正确映射我们的实例。one-to-manyTypeToken版本 2在玩了上面的解决方案之后,我想出了下面的deserialiser:class OneOrManyJsonDeserializer implements JsonDeserializer<List<?>> {&nbsp; &nbsp; @Override&nbsp; &nbsp; public List<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {&nbsp; &nbsp; &nbsp; &nbsp; final Type elementType = $Gson$Types.getCollectionElementType(typeOfT, List.class);&nbsp; &nbsp; &nbsp; &nbsp; if (json instanceof JsonArray) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final JsonArray array = (JsonArray) json;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final int size = array.size();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (size == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Collections.emptyList();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final List<?> suites = new ArrayList<>(size);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < size; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; suites.add(context.deserialize(array.get(i), elementType));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return suites;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; Object suite = context.deserialize(json, elementType);&nbsp; &nbsp; &nbsp; &nbsp; return Collections.singletonList(suite);&nbsp; &nbsp; }}我们不需要定制它。使用类,我们可以获得元素的类型并反序列化内部元素。简单用法:$Gson$Typesimport 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 {&nbsp; &nbsp; public static void main(String[] args) throws Exception {&nbsp; &nbsp; &nbsp; &nbsp; File jsonFile = new File("./resource/test.json").getAbsoluteFile();&nbsp; &nbsp; &nbsp; &nbsp; Gson gson = new GsonBuilder()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .registerTypeAdapter(List.class, new OneOrManyJsonDeserializer())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .setPrettyPrinting()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .create();&nbsp; &nbsp; &nbsp; &nbsp; TestResponse response = gson.fromJson(new FileReader(jsonFile), TestResponse.class);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(response);&nbsp; &nbsp; }}上面的代码也应该适合你。

森栏

我认为你可以使用杰克逊。ObjectMapper&nbsp;mapper&nbsp;=&nbsp;new&nbsp;ObjectMapper(); List<ChromeJsonModel>&nbsp;participantJsonList&nbsp;=&nbsp;mapper.readValue(jsonString,&nbsp;new&nbsp;TypeReference<List<ChromeJsonModel>>(){});

婷婷同学_

在你的根元素是 json 对象:json{&nbsp; &nbsp; <---- HERE YOU HAVE "OBJECT"&nbsp; "test-run": {&nbsp; &nbsp; "duration": 508.56199999999995,&nbsp; &nbsp; "result": "Passed",&nbsp; &nbsp; ...&nbsp; &nbsp;}}改变:List<ChromeJsonModel> jsonModelList = (List<ChromeJsonModel>) ... ;自:ChromeJsonModel jsonModelList = (ChromeJsonModel) ... ;您可以尝试在那里生成POJO:http://pojo.sodhanalibrary.com/
随时随地看视频慕课网APP

相关分类

Java
我要回答