I am trying to find a clean way of parsing nested properties from a payload from an API
.
Here is a rough generalisation of the JSON
payload:
{
"root": {
"data": {
"value": [
{
"user": {
"id": "1",
"name": {
"first": "x",
"last": "y"
}
}
}
]
}
}
}
My goal is to have an array of User
objects which have firstName
and lastName
fields.
Does anyone know a good way to parse this cleanly?
Right now I am trying to create a Wrapper
class and within that have static inner classes for data, value, user etc. but this seems like a messy way of doing this just to read the array of first/last properties.
I am using restTemplate.exchange()
to call the endpoint.
JsonPath library allows one to select only required fields and thn you can use Jackson
to convert raw data to POJO
class. Example solution could look as follows:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.jayway.jsonpath.JsonPath;
import java.io.File;
import java.util.List;
import java.util.Map;
public class JsonPathApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
List<Map> nodes = JsonPath.parse(jsonFile).read("$..value[*].user.name");
ObjectMapper mapper = new ObjectMapper();
CollectionType usersType = mapper.getTypeFactory().constructCollectionType(List.class, User.class);
List<User> users = mapper.convertValue(nodes, usersType);
System.out.println(users);
}
}
class User {
@JsonProperty("first")
private String firstName;
@JsonProperty("last")
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "User{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
Above code prints:
[User{firstName='x', lastName='y'}]