如何使用java gson解析动态json对象值

问题描述 投票:0回答:3

我有2节课

class X {
  public String name;
  public int age;
}
class Y {
  public float score;
}

json是这样的

{
  "type": "X",
  "data": {
    "name": "myname",
    "age": 20
  }
}

{
  "type": "Y",
  "data": {
    "score": 10
  }
}

如何用 gson 解析 json,但如果 type 字段是

X
那么数据将是
X
类实例

java json gson
3个回答
0
投票

您想要根据 type 元素的值反序列化 JSON。因此,您解析 JSON 并提取 type 元素的值。然后提取 data 元素并使用 Gson 将其反序列化为 Java 对象。

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class GsonTest {

    public static void main(String[] args) {
        String json = """
{
  "type": "X",
  "data": {
    "name": "myname",
    "age": 20
  }
}
""";
        JsonElement root = JsonParser.parseString(json);
        JsonObject obj = root.getAsJsonObject();
        JsonElement typeElem = obj.get("type");
        String type = typeElem.getAsString();
        JsonElement dataElem = obj.get("data");
        Gson gson = new Gson();
        Class<?> theClass;
        if ("X".equals(type)) {
            theClass = X.class;
        }
        else if ("Y".equals(type)) {
            theClass = Y.class;
        }
        else {
            theClass = null;
        }
        if (theClass != null) {
            Object result = gson.fromJson(dataElem, theClass);
            System.out.println(result);
        }
    }
}

上面的代码使用了Java 15中添加的文本块

我向类 X 添加了

toString
方法:

public String toString() {
    return String.format("%s:%d", name, age);
}

当我运行上面的代码时,我得到以下信息:

myname:20

请注意,通常会创建类

X
和类
Y
JavaBeans,即您需要添加“getters”和“setters”。

这是完整的代码:

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class GsonTest {

    public static void main(String[] args) {
        String json = """
{
  "type": "Y",
  "data": {
    "score": 10
  }
}
""";
        JsonElement root = JsonParser.parseString(json);
        JsonObject obj = root.getAsJsonObject();
        JsonElement typeElem = obj.get("type");
        String type = typeElem.getAsString();
        JsonElement dataElem = obj.get("data");
        Gson gson = new Gson();
        Class<?> theClass;
        if ("X".equals(type)) {
            theClass = X.class;
        }
        else if ("Y".equals(type)) {
            theClass = Y.class;
        }
        else {
            theClass = null;
        }
        if (theClass != null) {
            Object result = gson.fromJson(dataElem, theClass);
            System.out.println(result);
        }
    }
}

class X {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return String.format("%s:%d", name, age);
    }
}

class Y {
    private float score;

    public float getScore() {
        return score;
    }

    public void setScore(float score) {
        this.score = score;
    }

    public String toString() {
        return Float.toString(score);
    }
}

参考Gson使用指南


0
投票

我在向谷歌吟游诗人提出一些问题后发现如何......

public static class CustomTypeAdapter extends TypeAdapter<Object> {
    @Override
    public void write(JsonWriter out, Object value) {

    }

    @Override
    public Object read(JsonReader reader) {
        JsonObject jsonObject = JsonParser.parseReader(reader).getAsJsonObject();

        String type = jsonObject.get("type").getAsString();

        System.out.println(type);

        return switch (type) {
            case "X" -> new Gson().fromJson(jsonObject.get("data"), X.class);
            case "Y" -> new Gson().fromJson(jsonObject.get("data"), Y.class);
            default -> throw new JsonParseException("Unknown type: " + type);
        };
    }
}

然后我就这样使用

JsonReader reader = new Gson().newJsonReader(new StringReader("{\"type\":\"X\",\"data\":{\"name\":\"Name\",\"age\":10}}"));

Object output = new CustomTypeAdapter().read(reader);

System.out.println(((X) output).name);

但是我不知道为什么要延长

TypeAdapter<Object>
..我认为我不需要它。


0
投票
var m = new TreeMap();
m.put("type", X.class.getSimpleName());
m.put("data", new X("myname", 20));

var gson = new Gson();
var json = gson.toJson(m);

如果您不想创建自定义适配器,请尝试使用地图!
这可能是最简单的解决方案之一

© www.soinside.com 2019 - 2024. All rights reserved.