Organized output of JSON response in Java using GSON

E. Otero

Today, I decided to attempt at creating an application for myself that would display past and present football fixtures for the current 2015-2016 season using Java.

I currently cannot seem to figure out how to display the JSON properly. The web API endpoint is: http://api.football-data.org/v1/teams/81/fixtures (there is a 50 request limit/day without an API token). I am attempting to use GSON to parse the JSON, but the documentation seems to be going over my head.

Here is the code I have so far:

FCBFixtures.java

import java.io.*;
import java.net.*;
import com.google.gson.*;

public class FCBFixtures {

  private static String getJSON(String url, int timeout) {
    HttpURLConnection c = null;
    try {
      URL u = new URL(url);
      c = (HttpURLConnection) u.openConnection();
      c.setRequestMethod("GET");
      c.setRequestProperty("Content-length", "0");
      c.setRequestProperty("X-Auth-Token", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
      c.setUseCaches(false);
      c.setAllowUserInteraction(false);
      c.setConnectTimeout(timeout);
      c.setReadTimeout(timeout);
      c.connect();
      int status = c.getResponseCode();

      switch (status) {
        case 200:
        case 201:
          BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
          StringBuilder sb = new StringBuilder();
          String line;
          while ((line = br.readLine()) != null) {
            sb.append(line+"\n");
          }
          br.close();
          return sb.toString();
      }

    } catch (IOException ex) {
        System.out.println(ex.getMessage());
        System.exit(1);
    } finally {
      if (c != null) {
        try {
          c.disconnect();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            System.exit(1);
        }
      }
    }
    return null;
  }

  public static void main(String[] args) {
      String json = getJSON("http://api.football-data.org/v1/teams/81/fixtures", 500);
      Data data = new Gson().fromJson(json, Data.class);
      System.out.println(data);
  }
}

Data.java

import java.util.List;

public class Data {
    private String date;
    private String status;
    private Integer matchday;
    private String homeTeamName;
    private String awayTeamName;
    private Integer goalsHomeTeam;
    private Integer goalsAwayTeam;
    private List<Data> fixtures;

    public String getDate() { return date; }
    public String getStatus() { return status; }
    public Integer getMatchday() { return matchday; }
    public String getHomeTeamName() { return homeTeamName; }
    public String getAwayTeamName() { return awayTeamName; }
    public Integer getGoalsHomeTeam() { return goalsHomeTeam; }
    public Integer getGoalsAwayTeam() { return goalsAwayTeam; }
    public List<Data> getFixtures() { return fixtures; }

    public void setDate(String date) { this.date = date; }
    public void setStatus(String status) { this.status = status; }
    public void setMatchday(Integer matchday) { this.matchday = matchday; }
    public void setHomeTeamName(String homeTeamName) { this.homeTeamName = homeTeamName; }
    public void setAwayTeamName(String awayTeamName) { this.awayTeamName = awayTeamName; }
    public void setGoalsHomeTeam(Integer goalsHomeTeam) { this.goalsHomeTeam = goalsHomeTeam; }
    public void setGoalsAwayTeam(Integer goalsAwayTeam) { this.goalsAwayTeam = goalsAwayTeam; }
    public void setFixtures(List<Data> fixtures) { this.fixtures = fixtures; }

    public String toString() {
        if (date!=null) { //it's messy, coded it quickly but it works
            String[] split = date.split("T");
            String[] split2 = split[0].split("-");
            date = split2[1]+"/"+split2[2]+"/"+split2[0];
            String[] split3 = split[1].split(":");
            Integer hour = Integer.parseInt(split3[0])-7; //convert to eastern
            date += " "+hour+":"+split3[1];
        }
        String output = String.format("\n Fixtures:%-1s Matchday:%-1d Date:%-18s Home Team:%-25s Away Team:%-25s", fixtures, matchday, date, homeTeamName, awayTeamName);
        return output;
    }
}

I would like it in the end to output each matchday on its own line and each variable being properly spaced. Any help/direction would be very much appreciated. I have not had any experience with GSON before; however, I have used JSOUP before, just as some extra information on my knowledge and the situation.

Also, the cURL request is (without 'X-Auth-Token'): curl -H 'X-Response-Control: minified' -X GET http://api.football-data.org/v1/teams/66/fixtures

ug_

When using GSON and similar JSON library's its critical you have you data structures matching what the JSON structure. Looking at the JSON response from the server I see:

{
    "_links": {
        "_self": {
            "href": "http://api.football-data.org/v1/teams/81/fixtures"
        },
        "team": {
            "href": "http://api.football-data.org/v1/teams/81"
        }
    },
    "count": 44,
    "fixtures": [
        {
            "_links": {
                "self": {
                    "href": "http://api.football-data.org/v1/fixtures/147488"
                },
                "soccerseason": {
                    "href": "http://api.football-data.org/v1/soccerseasons/399"
                },
                "homeTeam": {
                    "href": "http://api.football-data.org/v1/teams/77"
                },
                "awayTeam": {
                    "href": "http://api.football-data.org/v1/teams/81"
                }
            },
            "date": "2015-08-23T16:30:00Z",
            "status": "FINISHED",
            "matchday": 1,
            "homeTeamName": "Athletic Club",
            "awayTeamName": "FC Barcelona",
            "result": {
                "goalsHomeTeam": 0,
                "goalsAwayTeam": 1
            }
        },  
        ...array continues with your Data objects...

It looks like your Data class is a fixture in the response. Heres 2 ways you can make GSON parse this correctly.

  • Make a container for your response which represents the outer object. This is probably the most common and best approach as it makes it very clear what the structure of the JSON looks like and follows the same format as the rest of the GSON parsing.

    public static class DataContainer {
        private int count;
        private Data[] fixtures;
    
        public int getCount() {
            return count;
        }
        public void setCount(int count) {
            this.count = count;
        }
    
        public Data[] getFixtures() {
            return fixtures;
        }
        public void setFixtures(Data[] fixtures) {
            this.fixtures = fixtures;
        }
    }
    

    then parse your Data objects out of the array

    DataContainer data = new Gson().fromJson(json, DataContainer.class);
    for(Data fixture : data.fixtures) {
        System.out.println(fixture);
    }
    
  • If you dont like the wrapper option you can also just parse the JSON as a JsonElement provided directly from the JsonParser. Then you can retreive the "fixtures" element from the object and convert that to an array of Data objects.

    JsonElement responseElement = new JsonParser().parse(json);
    Data[] dataArray = new Gson().fromJson(responseElement.getAsJsonObject().get("fixtures"), Data[].class);
    for(Data fixture : dataArray ) {
        System.out.println(fixture);
    }
    

The class name Data is quite vague, maybe consider mirroring the API's name of Fixture?

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related