在 Gson 中反序列化嵌套对象

时间:2021-06-14 21:58:19

标签: java json serialization gson

我的 JSON 响应是这样的:

{
  "General": {
    "Code": "xyz",
    "People": {
      "0": {
        "Name": "abc"
      },
      "1": {
        "Name": "def..."
      },
      "AddressData": {
        "Street": 123,
        "ZIP": 456
      }
    }
  }
}

对象 1 和对象 2 是同一个对象。它们将始终具有相同的属性。但是,根据我何时提取 JSON,它们可能不仅仅是两个对象。我不太确定如何使用 Gson 反序列化数据。

我尝试使用:

@SerializedName("People")
@Expose
private People[] People;

人们在哪里:

private class People {
    @SerializedName("Name")
    @Expose
    private String name;

    public People(String name){
        this.name = name
    }
}

但是,我收到错误

<块引用>

java.lang.IllegalStateException:预期为 BEGIN_ARRAY,但在第 1 行为 BEGIN_OBJECT

我的普通班是:

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class General {
    @SerializedName("Code")
    @Expose
    private String code;
    
    @SerializedName("People")
    @Expose
    private People[] people;
    
    @SerializedName("AddressData")
    @Expose
    private AddressData addressData;

    private class People {
        @SerializedName("Name")
        @Expose
        private String name;
        
        public People(String name){
            this.name = name;
        }
    }

    private class AddressData {
        @SerializedName("Street")
        @Expose
        private String street;
        
        @SerializedName("ZIP")
        @Expose
        private String zip;
    }
}

2 个答案:

答案 0 :(得分:1)

编写自定义序列化程序。这是问题中 JSON 的完整示例。

class PeopleSerializer implements JsonSerializer<People>, JsonDeserializer<People> {
    @Override
    public JsonElement serialize(People src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject obj = new JsonObject();
        for (Entry<Integer, PeopleName> entry : src.names.entrySet())
            obj.add(String.valueOf(entry.getKey()), context.serialize(entry.getValue()));
        obj.add("AddressData", context.serialize(src.addressData));
        return obj;
    }
    @Override
    public People deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        People people = new People();
        for (Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
            if (entry.getKey().equals("AddressData"))
                people.addressData = context.deserialize(entry.getValue(), AddressData.class);
            else
                people.names.put(Integer.valueOf(entry.getKey()), context.deserialize(entry.getValue(), PeopleName.class));
        }
        return people;
    }
}

测试

public class Test {
    public static void main(String[] args) throws Exception {
        String json = "{\r\n" + 
                      "  \"General\": {\r\n" + 
                      "    \"Code\": \"xyz\",\r\n" + 
                      "    \"People\": {\r\n" + 
                      "      \"0\": {\r\n" + 
                      "        \"Name\": \"abc\"\r\n" + 
                      "      },\r\n" + 
                      "      \"1\": {\r\n" + 
                      "        \"Name\": \"def...\"\r\n" + 
                      "      },\r\n" + 
                      "      \"AddressData\": {\r\n" + 
                      "        \"Street\": 123,\r\n" + 
                      "        \"ZIP\": 456\r\n" + 
                      "      }\r\n" + 
                      "    }\r\n" + 
                      "  }\r\n" + 
                      "}";
        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                .create();
        
        Root root = gson.fromJson(json, Root.class);
        System.out.println(root);
        
        gson.toJson(root, System.out);
    }
}
class Root {
    General general;
    @Override
    public String toString() {
        return "Root[general=" + this.general + "]";
    }
}
class General {
    String code;
    People people;
    @Override
    public String toString() {
        return "General[code=" + this.code + ", people=" + this.people + "]";
    }
}
@JsonAdapter(PeopleSerializer.class)
class People {
    Map<Integer, PeopleName> names = new TreeMap<>();
    AddressData addressData;
    @Override
    public String toString() {
        return "People[names=" + this.names + ", addressData=" + this.addressData + "]";
    }
}
class PeopleName {
    String name;
    @Override
    public String toString() {
        return "PeopleName[name=" + this.name + "]";
    }
}
class AddressData {
    Integer street;
    @SerializedName("ZIP")
    Integer zip;
    @Override
    public String toString() {
        return "AddressData[street=" + this.street + ", zip=" + this.zip + "]";
    }
}

输出

Root[general=General[code=xyz, people=People[names={0=PeopleName[name=abc], 1=PeopleName[name=def...]}, addressData=AddressData[street=123, zip=456]]]]
{"General":{"Code":"xyz","People":{"0":{"Name":"abc"},"1":{"Name":"def..."},"AddressData":{"Street":123,"ZIP":456}}}}

答案 1 :(得分:0)

对象人物是一张地图。对象 1 和 2 是键。我要睡觉了:)

相关问题