【问题标题】:How to convert JSON string to a JAVA object when the structure is different结构不同时如何将JSON字符串转换为JAVA对象
【发布时间】:2014-07-30 07:30:52
【问题描述】:

我正在尝试从 json 字符串创建对象的实例。 这是我的对象:

public class Person {
    String name;
    String address;
}

这是我的转换器:

Gson gson = new Gson();
Person p = gson.fromJson(str, Person.class);

问题是我的输入字符串格式可能比我的 Person 对象更复杂,例如:

{
  "name":"itay",
  "address":{
       "street":"my street",
       "number":"10"
     }
}

或者address 的值可以是一个简单的字符串(在这种情况下我没有问题)。 我希望 p.address 包含 json 对象作为字符串。 这只是我的问题的一个例子,实际上“地址”要复杂得多,结构是未知的。

我的解决方案是将Person 类更改为:

public class BetterPerson {
    String name;
    Object address;
}

现在,address 是一个对象,我可以使用 .toString() 来获取值。

有更好的方法吗?

【问题讨论】:

    标签: java json type-conversion gson


    【解决方案1】:

    您可以尝试使用 JsonDeserializer 根据运行时确定的 JSON 结构对其进行反序列化。

    更多信息请查看GSON Deserialiser Example

    示例代码:

    class Person {
        private String name;
        private Object address;
        // getter & setter
    }
    
    class Address {
        private String street;
        private String number;
        // getter & setter
    }
    
    ...
    
    class PersonDeserializer implements JsonDeserializer<Person> {
    
        @Override
        public Person deserialize(final JsonElement json, final Type typeOfT,
                final JsonDeserializationContext context) throws JsonParseException {
    
            JsonObject jsonObject = json.getAsJsonObject();
    
            Person person = new Person();
            person.setName(jsonObject.get("name").getAsString());
    
            JsonElement jsonElement = jsonObject.get("address");
            if (!jsonElement.isJsonObject()) {
                String address = jsonElement.getAsString();
                person.setAddress(address);
            } else {
                JsonObject addressJsonObject = (JsonObject) jsonElement;
    
                Address address = new Address();
                address.setNumber(addressJsonObject.get("number").getAsString());
                address.setStreet(addressJsonObject.get("street").getAsString());
                person.setAddress(address);
            }
    
            return person;
        }
    }
    
    Person data = new GsonBuilder()
            .registerTypeAdapter(Person.class, new PersonDeserializer()).create()
            .fromJson(jsonString, Person.class);
    
    if (data.getAddress() instanceof Address) {
        Address address = (Address) data.getAddress();
    } else {
        String address = (String) data.getAddress();
    }
    

    你也可以尝试HashMap&lt;String,String&gt; address而不使用额外的Address POJO类,如果它的结构也是未知的。

    您也可以这样做,如果地址是字符串,则构造地址对象并在街道变量中设置地址字符串,如下所示:

    class Person {
        private String name;
        private Address address;
        // getter & setter
    }
    
    
    ...
    JsonElement jsonElement = jsonObject.get("address");
    if (!jsonElement.isJsonObject()) {
        String address = jsonElement.getAsString();
        Address obj = new Address();
        obj.setStreet(address);
        person.setAddress(obj);
    }else{...}
    

    【讨论】:

    • 正如我所说 - “地址”结构是未知的(仅在运行时确定)
    • 我只是在更新我的帖子。等一下
    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 2015-05-24
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 2011-08-30
    相关资源
    最近更新 更多