Java 如何构造元素数量动态的JSON?
我需要构造一个类似这样的JSON对象(见下文)。其中一个棘手的部分是“accountInfo”是动态的,因为将有0到多个键值对Java 如何构造元素数量动态的JSON?,java,json,jackson,Java,Json,Jackson,我需要构造一个类似这样的JSON对象(见下文)。其中一个棘手的部分是“accountInfo”是动态的,因为将有0到多个键值对 { "zipCode": "123", "name": "bob", "partner": { "from": "someCompany", "accountNumber": "56789", "accountInfo": [ { "key": "a", "value": "098"
{
"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;
}
公共类ToJson{
私有字符串zipCode;
私有字符串名称;
私人合伙人;
私有BonuType BonuType;
}
公共课伙伴{
来自的私有字符串;
私有字符串accountNumber;
私人帐户信息;
}
公共类AccountInfo{
私有列表额外数据;
}
公共类外部数据{
私钥;
私有字符串值;
}
公共类BonuType{
私有字符串码;
}
这样做有意义吗?我会使用类似Jackson的东西来设置POJOToJson.setZipCode(“123”)
等的值
或者,有没有一种更简单/更好的方法可以这样做?下面是一些用于反序列化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 + "]";
}
}
为了使gson成功地反序列化,必须为类成员变量定义适当的setter方法,并且每个类必须有一个零参数构造函数(当没有显式定义构造函数时,这是隐含的)。我还定义了每个方法的toString
方法,以便于读取输出
请注意,Partner
类使用了一个私有列表accountInfo代码>表示帐户信息数据。因为JSON数组中的每个对象都有一个“键”和“值”,所以gson能够将它们解析为Map
对象。您可以将它们表示为自定义对象,但这不是必需的
一些最后的想法:
我不知道为什么将BonuType表示为对象,因为它只有一个字段。您可以简单地将其表示为顶级对象中的单个名称-值对:“bonusType”:“credit”
这样做有意义吗
在大多数情况下是的。当您有复杂的数据结构时,使用表示数据模型的类通常是一个好主意。另一种方法是使用更通用的类和对象来解析数据,这往往会导致代码更长、可读性差、可维护性差。此外,大多数现代IDE都可以快速生成上述数据模型类。我只用了几分钟就在Eclipse中生成了这些。您基本上只需要定义类成员变量,其余的很容易生成,这节省了您的时间
另一方面,大多数解析器在反序列化JSON数据时会忽略额外的字段,这意味着无论何时需要新字段,都必须更新对象。如果将数据表示为映射
,则解析器将能够拉入所有字段。这就是为什么它取决于您的用例,哪种解析方法是最好的。如果您希望经常向JSON添加新字段,那么使用更通用的数据表示可能会减少维护。但是,如果您经常更改JSON的现有结构,或者不希望JSON中有太多更改,那么定制对象方法的维护可能会更少 [
{
“钥匙”:“a”,
“值”:“098”
},
{
“密钥”:“b”,
“值”:“765”
}
]
是一个ExtraData类的列表
所以搭档课应该是这样的
public class Partner {
private String from;
private String accountNumber;
private ArrayList<ExtraData> accountInfo;
}
公共类合作伙伴{
来自的私有字符串;
私有字符串accountNumber;
私人ArrayList accountInfo;
}
如果您这样做:私人帐户信息可能会转换为JSON对象而不是数组的代码>。您需要类似于私有列表accountInfo
您甚至可能不需要创建ExtraData
类,您可以尝试使用Map
。至于“这有意义吗?”-是的,它对这样的数据肯定有意义,因为它使解析变得更简单,但这实际上取决于您的用例。添加一些解释。不要只发布答案
public class Partner {
private String from;
private String accountNumber;
private ArrayList<ExtraData> accountInfo;
}