如何构建具有动态元素数量的 JSON?

2024-05-01

我需要构造一个看起来像这样的 JSON 对象(见下文)。棘手的部分之一是“accountInfo”是动态的,因为会有 0 到多个键值对。

{
  "zipCode": "123",
  "name": "bob",
  "partner": {
    "from": "someCompany",
    "accountNumber": "56789",
    "accountInfo": [
      {
        "key": "a",
        "value": "098"
      },
      {
        "key": "b",
        "value": "765"
      }
    ]
  },
  "bonusType": {
    "code": "credit"
  }
}

我正在尝试思考解决这个问题的最佳方法。我正在考虑创建类来表示对象,然后将其转换为 JSON。对于动态键值对,我将使用一个列表来保存它们。

所以我会有这样的东西:

public class ToJson{
    private String zipCode;
    private String name;
    private Partner partner;
    private BonusType bonusType;
}

public class Partner{
    private String from;
    private String accountNumber;
    private AccountInfo accountInfo;
}

public class AccountInfo{
    private List<ExtraData> extra_data; 
}

public class ExtraData{
    private String key;
    private String value;
}

public class BonusType{
    private String code;
}

这样做有意义吗?我会使用 Jackson 之类的东西来设置 POJO 的值ToJson.setZipCode("123") etc.

或者有一个更简单/更好的方法我应该做这样的事情吗?


这是一些使用的示例代码gson https://github.com/google/gson反序列化 JSON 数据:

一、控制器类:

package gson;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import com.google.gson.Gson;

public class GsonMain {

    public static void main(String[] args) throws IOException {
        Gson gson = new Gson();
        byte[] jsonBytes = Files.readAllBytes(Paths.get("./src/main/java/gson/jsonData.json"));
        String json = new String(jsonBytes);

        // Deserialization
        ToJson result = gson.fromJson(json, ToJson.class);

        System.out.println("RESULTS: "+result.toString());
    }

}

接下来是数据模型类。这是顶级对象:

package gson;

public class ToJson {
    private String zipCode;
    private String name;
    private Partner partner;
    private BonusType bonusType;

    public String getZipCode() {
        return zipCode;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    public String getName() {
        return name;
    }

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

    public Partner getPartner() {
        return partner;
    }

    public void setPartner(Partner partner) {
        this.partner = partner;
    }

    public BonusType getBonusType() {
        return bonusType;
    }

    public void setBonusType(BonusType bonusType) {
        this.bonusType = bonusType;
    }

    @Override
    public String toString() {
        return "ToJson [zipCode=" + zipCode + ", name=" + name + ", partner=" + partner + ", bonusType=" + bonusType
                + "]";
    }
}

这是合作伙伴:

package gson;

import java.util.List;
import java.util.Map;

public class Partner {
    private String from;
    private String accountNumber;
    private List<Map<String, String>> accountInfo;

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
    }

    public List<Map<String, String>> getAccountInfo() {
        return accountInfo;
    }

    public void setAccountInfo(List<Map<String, String>> accountInfo) {
        this.accountInfo = accountInfo;
    }

    @Override
    public String toString() {
        return "Partner [from=" + from + ", accountNumber=" + accountNumber + ", accountInfo=" + accountInfo + "]";
    }
}

最后,这是 BonusType:

package gson;

public class BonusType {
    private String code;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public String toString() {
        return "BonusType [code=" + code + "]";
    }
}

为了使 gson 成功反序列化,必须为类成员变量定义适当的 setter 方法,并且每个类必须有一个零参数构造函数(当没有显式定义构造函数时,这是隐含的)。我还定义了toString每个方法都可以轻松读取输出。

请注意,Partner类使用一个private List<Map<String, String>> accountInfo;代表帐户信息数据。由于 JSON 数组中的每个对象都有一个“键”和“值”,gson 能够将它们解析为Map对象。您可以将它们表示为自定义对象,但这不是必需的。

最后一些想法:

我不确定为什么你将 BonusType 表示为一个对象,因为它只有一个字段。您可以简单地将其表示为顶级对象中的单个名称值对:"bonusType":"credit"

这样做有意义吗?

大多数情况下是的。当您拥有复杂的数据结构时,使用代表数据模型的类通常是一个好主意。另一种方法是使用更通用的类和对象来解析数据,但这往往会导致代码更长、可读性较差、可维护性较差。此外,大多数现代 IDE 都可以快速生成类似上述的数据模型类。我只花了几分钟就在 Eclipse 中生成了这些内容。你基本上只需要定义类成员变量,其余的很容易生成,这节省了你的时间。

另一方面,大多数解析器在反序列化 JSON 数据时会忽略额外的字段,这意味着每当需要新字段时都必须更新对象。如果您将数据表示为Map<String,Object>相反,解析器将能够提取所有字段。这就是为什么哪种解析方法最好取决于您的用例。如果您希望经常向 JSON 添加新字段,那么使用更通用的数据表示形式可能会减少维护工作。但是,如果您经常更改 JSON 的现有结构,或者不期望 JSON 发生太大变化,那么自定义对象方法可能需要较少的维护。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何构建具有动态元素数量的 JSON? 的相关文章

  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • 多个 Maven 配置文件激活多个 Spring 配置文件

    我想在 Maven 中构建一个环境 在其中我想根据哪些 Maven 配置文件处于活动状态来累积激活多个 spring 配置文件 目前我的 pom xml 的相关部分如下所示
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • 如何格式化 Json 输出

    请帮助我如何获取 JSON 输出 如下所示 costMethod Average fundingDate 2008 10 02 fundingAmount 2510959 95 代替 type sma costMethod Average
  • getResourceAsStream() 可以找到 jar 文件之外的文件吗?

    我正在开发一个应用程序 该应用程序使用一个加载配置文件的库 InputStream in getClass getResourceAsStream resource 然后我的应用程序打包在一个 jar文件 如果resource是在里面 ja
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • 如何在 Python 中追加到 JSON 文件?

    我有一个 JSON 文件 其中包含 67790 1 kwh 319 4 现在我创建一个字典a dict我需要将其附加到 JSON 文件中 我尝试了这段代码 with open DATA FILENAME a as f json obj js
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 使用 xpath 和 vtd-xml 以字符串形式获取元素的子节点和文本

    这是我的 XML 的一部分

随机推荐