How to convert JSON string to a JAVA object when t

2020-02-02 03:02发布

问题:

I'm trying to create an instance of an object from a json string. 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:

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

Or address's value can be a simple string (in that case I have no problem). I want p.address to contain the json object as string. 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:

public class BetterPerson {
    String name;
    Object address;
}

Now, address is an object and I can use .toString() to get the value.

Is there a better way of doing this?

回答1:

You can try with JsonDeserializer to deserializer it as per JSON structure that is determined at run-time.

For more info have a look at GSON Deserialiser Example

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.

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:

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