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