简体   繁体   English

结构不同时如何将JSON字符串转换为JAVA对象

[英]How to convert JSON string to a JAVA object when the structure is different

I'm trying to create an instance of an object from a json string. 我正在尝试从json字符串创建对象的实例。 This is my object: 这是我的对象:

public class Person {
    String name;
    String address;
}

and this is my converter: 这是我的转换器:

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

The problem is that my input string format can be more complex than my Person object, for example: 问题是我的输入字符串格式可能比我的Person对象复杂,例如:

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

Or address 's value can be a simple string (in that case I have no problem). address的值可以是一个简单的字符串(在这种情况下,我没有问题)。 I want p.address to contain the json object as string. 我希望p.address包含json对象作为字符串。 This is only an example of my problem, in fact, the "address" is much more complex and the structure is unknown. 这只是我的问题的一个例子,实际上,“地址”要复杂得多,结构未知。

My solution is changing the Person class to: 我的解决方案是将Person类更改为:

public class BetterPerson {
    String name;
    Object address;
}

Now, address is an object and I can use .toString() to get the value. 现在, address是一个对象,我可以使用.toString()获取值。

Is there a better way of doing this? 有更好的方法吗?

You can try with JsonDeserializer to deserializer it as per JSON structure that is determined at run-time. 您可以尝试使用JsonDeserializer根据运行时确定的JSON结构将其反序列化。

For more info have a look at GSON Deserialiser Example 有关更多信息,请查看GSON Deserialiser示例

Sample code: 样例代码:

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();
}

You can try HashMap<String,String> address without using extra Address POJO class as well if it's structure is also not known. 如果还不了解HashMap<String,String> address的结构,也可以使用它而不使用额外的Address POJO类。

you can do in this way as well where if address is String then construct Address object and set the address string in street variable as illustrated below: 您也可以在地址为String的情况下构造地址对象,并在street变量中设置地址字符串,如下所示:

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{...}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM