简体   繁体   中英

Deserializing complex JSON response using Jackson

I am developing my web application backend using Spring. In particular, my application manages data on soccer teams and their players.

My application interacts with a third party REST API to fetch team and player data.

As for the teams, I created a Team entity as follows:

@Data
@Table(name = "team")
@Entity
public class Team {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Long id;
    private String name;
    private String logoUrl;
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "team")
    private Set<Player> players;
}

The response that comes to me from the API, however, has a particular structure and contains an array of Teams in the "response" node.

Here is the structure of the response:

{
   "get":"teams",
   "parameters":{
      "league":"135",
      "season":"2020"
   },
   "errors":[
      
   ],
   "results":20,
   "paging":{
      "current":1,
      "total":1
   },
   "response":[
      {
         "team":{
            "id":487,
            "name":"Lazio",
            "country":"Italy",
            "founded":1900,
            "national":false,
            "logo":"https:\/\/media.api-sports.io\/football\/teams\/487.png"
         },
         "venue":{
            "id":910,
            "name":"Stadio Olimpico",
            "address":"Viale dei Gladiatori, 2 \/ Via del Foro Italico",
            "city":"Roma",
            "capacity":68530,
            "surface":"grass",
            "image":"https:\/\/media.api-sports.io\/football\/venues\/910.png"
         }
      },
      {
         "team":{
            "id":488,
            "name":"Sassuolo",
            "country":"Italy",
            "founded":1922,
            "national":false,
            "logo":"https:\/\/media.api-sports.io\/football\/teams\/488.png"
         },
         "venue":{
            "id":935,
            "name":"MAPEI Stadium - Citt\u00e0 del Tricolore",
            "address":"Piazza Azzuri d&apos;Italia, 1",
            "city":"Reggio nell&apos;Emilia",
            "capacity":23717,
            "surface":"grass",
            "image":"https:\/\/media.api-sports.io\/football\/venues\/935.png"
         }
      },
      ... // Other team objects
   ]
}

How can I parse the answer to get a List<Team> using the Jackson library?

You should create classes for Jackson that match result structure then convert instances of those classes to your Team class. Using same class for JPA entity and for Jackson deserialization is a bad idea.

There are online services that allow generating classes like this. For example this one https://json2csharp.com/json-to-pojo generated classes like this:

// import com.fasterxml.jackson.databind.ObjectMapper; // version 2.11.1
// import com.fasterxml.jackson.annotation.JsonProperty; // version 2.11.1
/* ObjectMapper om = new ObjectMapper();
Root root = om.readValue(myJsonString), Root.class); */
public class Parameters{
    public String league;
    public String season;
}

public class Paging{
    public int current;
    public int total;
}

public class Team{
    public int id;
    public String name;
    public String country;
    public int founded;
    public boolean national;
    public String logo;
}

public class Venue{
    public int id;
    public String name;
    public String address;
    public String city;
    public int capacity;
    public String surface;
    public String image;
}

public class Response{
    public Team team;
    public Venue venue;
}

public class Root{
    public String get;
    public Parameters parameters;
    public List<Object> errors;
    public int results;
    public Paging paging;
    public List<Response> response;
}

As @Sankozi said you can modelize your java pojos for json deserialization. Then use an ObjectMapper for deserialization like :

ObjectMapper mapper = new ObjectMapper();
                
CollectionType javaType = mapper.getTypeFactory()
  .constructCollectionType(List.class, Response.class);
                
List<Response> asList = mapper.readValue(jsonArray, javaType);
                
List<Team> teams = asList.stream()
    
  .flatMap(response -> response.getTeam())
                        
  .collect(Collectors.toList());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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