gpt4 book ai didi

java - Gson 中的自循环引用

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:26:30 31 4
gpt4 key购买 nike

我在反序列化遵循这种格式的 Json 数组时遇到了一些问题:

[
{
"ChildList":[
{
"ChildList":[

],
"Id":110,
"Name":"Books",
"ApplicationCount":0
}
],
"Id":110,
"Name":"Books",
"ApplicationCount":0
}
]

它基本上是一个类别数组,其中每个类别还可以有一个子类别列表,依此类推。我的类模型看起来有点像这样:

public class ArrayOfCategory{
protected List<Category> category;
}

public class Category{

protected ArrayOfCategory childList;
protected int id;
protected String name;
protected int applicationCount;
}

现在,Gson 显然提示循环引用。鉴于我无法假设有多少级别的类别,是否有任何方法可以解析此 Json 输入?提前致谢。

编辑:以防万一有人遇到类似的问题,根据 Spaeth 的回答,我使用反射将解决方案应用于更一般的情况。唯一的要求是由 JSON 数组表示的对象列表包装在另一个类中(如我的示例中的 Category 和 ArrayOfCategory)。将以下代码应用于我的原始示例后,您只需调用“deserializeJson(jsonString,ArrayOfCategory.class)”,它就会按预期工作。

private <T> T deserializeJson(String stream, Class<T> clazz) throws PluginException {
try {
JsonElement je = new JsonParser().parse(stream);
if (je instanceof JsonArray) {
return deserializeJsonArray(clazz, je);
} else {
return new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create().fromJson(stream, clazz);
}
} catch (Exception e) {
throw new PluginException("Failed to parse json string: " + ((stream.length() > 20) ? stream.substring(0, 20) : stream) + "... to class " + clazz.getName());
}
}

private <T> T deserializeJsonArray(Class<T> clazz, JsonElement je) throws InstantiationException, IllegalAccessException {
ParameterizedType listField = (ParameterizedType) clazz.getDeclaredFields()[0].getGenericType();
final Type listType = listField.getActualTypeArguments()[0];
T ret = clazz.newInstance();
final Field retField = ret.getClass().getDeclaredFields()[0];
retField.setAccessible(true);
retField.set(ret, getListFromJsonArray((JsonArray) je,(Class<?>) listType));
return ret;
}

private <E> List<E> getListFromJsonArray(JsonArray je, Class<E> listType) {
Type collectionType = new TypeToken<List<E>>(){}.getType();
final GsonBuilder builder = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE);
Gson jsonParser = builder.create();
return jsonParser.fromJson(je, collectionType);
}

最佳答案

也许你可以试试这个:

    com.google.gson.Gson gson = new GsonBuilder().create();
InputStreamReader reader = new InputStreamReader(new FileInputStream(new File("/tmp/gson.txt")));
Collection<Category> fromJson = gson.fromJson(reader, new TypeToken<Collection<Category>>() {}.getType());
System.out.println(fromJson);

你会得到一个好的结果。

“魔法”发生在这里:new TypeToken<Collection<Category>>() {}.getType()

整个代码是:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.List;

import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

public class GsonCircularReference {

public class Category {
protected List<Category> childList;
protected int id;
protected String name;
protected int applicationCount;

public List<Category> getChildList() {
return childList;
}

public void setChildList(final List<Category> childList) {
this.childList = childList;
}

public int getId() {
return id;
}

public void setId(final int id) {
this.id = id;
}

public String getName() {
return name;
}

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

public int getApplicationCount() {
return applicationCount;
}

public void setApplicationCount(final int applicationCount) {
this.applicationCount = applicationCount;
}

@Override
public String toString() {
return "Category [category=" + childList + ", id=" + id + ", name=" + name + ", applicationCount="
+ applicationCount + "]";
}

}

public static void main(final String[] args) throws JsonSyntaxException, JsonIOException, FileNotFoundException {
com.google.gson.Gson gson = new GsonBuilder().create();
InputStreamReader reader = new InputStreamReader(new FileInputStream(new File("/tmp/gson.txt")));
Collection<Category> fromJson = gson.fromJson(reader, new TypeToken<Collection<Category>>() {}.getType());
System.out.println(fromJson);
}

}

JSON 文件是:

[
{
"childList":[
{
"childList":[
],
"id":110,
"Name":"Books",
"applicationCount":0
}
],
"id":110,
"name":"Books",
"applicationCount":0
}
]

关于java - Gson 中的自循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11058476/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com