Reputation: 3847
I have a json response that looks like this:
{
"id":"001",
"name":"Name",
"param_distance":"10",
"param_sampling":"2"
}
And I have two classes: Teste and Parameters
public class Test {
private int id;
private String name;
private Parameters params;
}
public class Parameters {
private double distance;
private int sampling;
}
My question is: is there a way to make Gson understand that some of the json attributes should go to the Parameters class, or the only way is to "manually" parse this ?
Well, just to make my comment in @MikO's answer more readable:
I'll add a list of an object to the json output, so json response should look like this:
{
"id":"001",
"name":"Name",
"param_distance":"10",
"param_sampling":"2",
"events":[
{
"id":"01",
"value":"22.5"
},
{
"id":"02",
"value":"31.0"
}
]
}
And the Deserializer class would look like this:
public class TestDeserializer implements JsonDeserializer<Test> {
@Override
public Test deserialize(JsonElement json, Type type,
JsonDeserializationContext context) throws JsonParseException {
JsonObject obj = json.getAsJsonObject();
Test test = new Test();
test.setId(obj.get("id").getAsInt());
test.setName(obj.get("name").getAsString());
Parameters params = new Parameters();
params.setDistance(obj.get("param_distance").getAsDouble());
params.setSampling(obj.get("param_sampling").getAsInt());
test.setParameters(params);
Gson eventGson = new Gson();
Type eventsType = new TypeToken<List<Event>>(){}.getType();
List<Event> eventList = eventGson.fromJson(obj.get("events"), eventsType);
test.setEvents(eventList);
return test;
}
}
And doing:
GsonBuilder gBuilder = new GsonBuilder();
gBuilder.registerTypeAdapter(Test.class, new TestDeserializer());
Gson gson = gBuilder.create();
Test test = gson.fromJson(reader, Test.class);
Gives me the test object the way I wanted.
Upvotes: 4
Views: 5053
Reputation: 18741
The way to make Gson understand it is to write a custom deserializer by creating a TypeAdapter
for your Test
class. You can find information in Gson's User Guide. It is not exactly a manual parsing, but it is not that different, since you have to tell Gson how to deal with each JSON value...
It should be something like this:
private class TestDeserializer implements JsonDeserializer<Test> {
public Test deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject obj = json.getAsJsonObject();
int id = obj.get("id").getAsInt();
String name = obj.get("name").getAsString();
double distance = obj.get("param_distance").getAsDouble();
int sampling = obj.get("param_sampling").getAsInt();
//assuming you have suitable constructors...
Test test = new Test(id, name, new Parameters(distance, sampling));
return test;
}
}
Then you have to register the TypeAdapter
with:
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(Test.class, new TestDeserializer());
And finally you just have to parse your JSON as usual, with:
gson.fromJson(yourJsonString, Test.class);
Gson will automatically use your custom deserializer to parse your JSON into your Test
class.
Upvotes: 3