Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用对象列表时,通过Gson读取JSON文件_Java_Json_Gson - Fatal编程技术网

Java 使用对象列表时,通过Gson读取JSON文件

Java 使用对象列表时,通过Gson读取JSON文件,java,json,gson,Java,Json,Gson,我尽可能地解释我的处境。我想用Gson读取一个JSON文件,其中包含一个对象列表。这个对象是基类,因为我有几个扩展它的对象 { "name":"Test", "url":"http://test.test", "script":[ { "actionId":1, "actionType":"click", "id":"testId", "redirect" : "http://google.de" }, { "actionId":2

我尽可能地解释我的处境。我想用Gson读取一个JSON文件,其中包含一个对象列表。这个对象是基类,因为我有几个扩展它的对象

{ 
    "name":"Test", 
    "url":"http://test.test", 
    "script":[ 
        { "actionId":1, "actionType":"click", "id":"testId", "redirect" : "http://google.de" },
        { "actionId":2, "actionType":"write", "id":"testId2", "content":"testContent" } 
    ] 
}
基类称为
ScriptElement
,它还包含每个子对象所需的一些值
ScriptInput
ScriptClickable
是子项。
如果我将列表转换为JSON,就会得到一个生成良好的JSON文件。但是当我读取JSON文件并将其转换回对象时,它只包含
ScriptElement
对象,并且缺少
ScriptInput
ScriptClickable
的附加信息好的,基于JSON结构,用这些属性创建一个类

public class User{
private String name;
private String url;
private ArrayList<Script>script;
}
public class Script{
private int actionId;
private String actionType;
private String id;
private String redirect;
}

好的,基于json结构,用这些属性创建一个类

public class User{
private String name;
private String url;
private ArrayList<Script>script;
}
public class Script{
private int actionId;
private String actionType;
private String id;
private String redirect;
}

这是一个典型的例子:之所以发生这种情况,是因为Gson对
ScriptElement
actionType
值之间的关系没有任何线索。你只需要告诉Gson这些是如何映射的

为简单起见,我假设您的映射如下:

最终课堂反应{
最终字符串名称=null;
最终URL=null;
最终列表脚本=null;
}
抽象类脚本元素{
final int actionId=Integer.valueOf(0);
最终字符串id=null;
}
final类ScriptClickable扩展了ScriptElement{
最终URL重定向=null;
}
final类ScriptInput扩展了ScriptElement{
最终字符串内容=null;
}
现在,只需注册一个
JsonDeserializer
,根据
actionType
属性值生成一个
ScriptElement

private static final Gson gson = new GsonBuilder()
        .registerTypeAdapter(ScriptElement.class, (JsonDeserializer<ScriptElement>) (jsonElement, type, context) -> {
            final String actionType = jsonElement.getAsJsonObject().getAsJsonPrimitive("actionType").getAsString();
            switch ( actionType ) {
            case "click":
                return context.deserialize(jsonElement, ScriptClickable.class);
            case "write":
                return context.deserialize(jsonElement, ScriptInput.class);
            default:
                throw new JsonParseException("Unrecognized action type: " + actionType);
            }
        })
        .create();
输出:

http://google.de
测试内容

有关多态对象反序列化的详细信息,请参见:


这是一个经典案例:发生这种情况是因为Gson对
ScriptElement
actionType
值之间的关系没有任何线索。你只需要告诉Gson这些是如何映射的

为简单起见,我假设您的映射如下:

最终课堂反应{
最终字符串名称=null;
最终URL=null;
最终列表脚本=null;
}
抽象类脚本元素{
final int actionId=Integer.valueOf(0);
最终字符串id=null;
}
final类ScriptClickable扩展了ScriptElement{
最终URL重定向=null;
}
final类ScriptInput扩展了ScriptElement{
最终字符串内容=null;
}
现在,只需注册一个
JsonDeserializer
,根据
actionType
属性值生成一个
ScriptElement

private static final Gson gson = new GsonBuilder()
        .registerTypeAdapter(ScriptElement.class, (JsonDeserializer<ScriptElement>) (jsonElement, type, context) -> {
            final String actionType = jsonElement.getAsJsonObject().getAsJsonPrimitive("actionType").getAsString();
            switch ( actionType ) {
            case "click":
                return context.deserialize(jsonElement, ScriptClickable.class);
            case "write":
                return context.deserialize(jsonElement, ScriptInput.class);
            default:
                throw new JsonParseException("Unrecognized action type: " + actionType);
            }
        })
        .create();
输出:

http://google.de
测试内容

有关多态对象反序列化的详细信息,请参见:



您至少可以向我们展示json文件<代码>{“名称”:“测试”,“url”:http://test.test,“脚本”:[{“actionId”:1,“actionType”:“单击”,“id”:“测试id”,“重定向”:http://google.de“},{actionId:2,“actionType”:“write”,“id”:“testId2”,“content”:“testContent”}]}我试图将其添加到主文本中,但是我得到的信息是代码无效。不知道为什么。你能编辑你的post-instade-fof-put评论吗?就像我说的,我不能。系统告诉我,我的代码包含错误,无法添加。您至少可以向我们显示json文件<代码>{“名称”:“测试”,“url”:http://test.test,“脚本”:[{“actionId”:1,“actionType”:“单击”,“id”:“测试id”,“重定向”:http://google.de“},{actionId:2,“actionType”:“write”,“id”:“testId2”,“content”:“testContent”}]}我试图将其添加到主文本中,但是我得到的信息是代码无效。不知道为什么。你能编辑你的post-instade-fof-put评论吗?就像我说的,我不能。系统告诉我,我的代码包含错误,无法添加。您好,您的用户类是正确的,它看起来很接近我的。但脚本只是一个基类,这个列表中的所有元素都是从脚本扩展而来的子类。像这样,
public类ScriptClickable扩展ScriptElement{@SerializedName(“redirect”)@Expose private String redirect;@Override public boolean execute(){//执行对ScriptClickable系统很重要的代码。out.println(“点击按钮”);返回true;}
我使用子类的原因是“execute”方法。基于脚本类,它做了一些不同的事情。你是什么意思!我根据您的脚本结构创建了脚本类,它将不起作用。execute方法是什么?您的元素应该与json结构的名称完全相同,否则它将不起作用您好,您的用户类是正确的,它看起来很接近我的。但脚本只是一个基类,这个列表中的所有元素都是从脚本扩展而来的子类。像这样,
public类ScriptClickable扩展ScriptElement{@SerializedName(“redirect”)@Expose private String redirect;@Override public boolean execute(){//执行对ScriptClickable系统很重要的代码。out.println(“点击按钮”);返回true;}
我使用子类的原因是“execute”方法。基于脚本类,它做了一些不同的事情。你是什么意思!我根据您的脚本结构创建了脚本类,它将不起作用。执行方法是什么?您的元素应该与json结构的名称完全相同,否则它将不起作用。我正在考虑使用类似的方法,但我认为会有一个更“实用”的解决方案