Search code examples
javajsonspringgsonpojo

Gson deserialization skip one quotation


I have to deserialise JSON. I use GSON library for this purpose. I am building a web application. The user fills up where he wants to fly, then the query is sent to the API and the result is returned.

Let us use an example of response:

{"success":true,"data":{"WAW":{"0":{"price":153,"airline":"LO","flight_number":678,"departure_at":"2019-08-05T17:40:00Z","return_at":"2019-08-20T14:35:00Z","expires_at":"2019-05-24T20:55:02Z"},"1":{"price":126,"airline":"A3","flight_number":881,"departure_at":"2019-11-21T11:00:00Z","return_at":"2019-11-26T16:05:00Z","expires_at":"2019-05-27T13:39:23Z"},"2":{"price":171,"airline":"KL","flight_number":900,"departure_at":"2019-09-12T02:40:00Z","return_at":"2019-09-18T17:30:00Z","expires_at":"2019-05-27T10:40:40Z"},"3":{"price":235,"airline":"B2","flight_number":972,"departure_at":"2019-06-12T07:20:00Z","return_at":"2019-06-18T17:30:00Z","expires_at":"2019-05-26T12:31:22Z"},"4":{"price":596,"airline":"TK","flight_number":422,"departure_at":"2019-06-20T00:10:00Z","return_at":"2019-06-24T13:05:00Z","expires_at":"2019-05-26T08:08:21Z"}}},"error":null,"currency":"EUR"}

I created a classes in this way: http://pojo.sodhanalibrary.com

The problem is that there is always the name of the place of arrival. In this case WAW = Warsaw.

gsonConvert.gson(output).getData().getWAW().getFirst().getAirline()

I want to avoid it because the place of arrival will depend on the choice of the user.


Solution

  • You should be able to simplify your data property to type: Map<String, Map<String, Flight>>. Where Flight POJO represents given flight. Model could look like below:

    class FlightResponse {
    
        private boolean success;
        private Map<String, Map<String, Flight>> data;
        private String error;
        private String currency;
    
        public Map<String, Flight> getFlatData() {
            return data.entrySet()
                    .stream()
                    .collect(HashMap::new, (m, e) -> m.putAll(e.getValue()), Map::putAll);
        }
    
        // getters, setters, toString
    }
    
    class Flight {
    
        private BigDecimal price;
        private String airline;
    
        @SerializedName("flight_number")
        private int flightNumber;
    
        @SerializedName("departure_at")
        private String departureAt;
    
        @SerializedName("return_at")
        private String returnAt;
    
        @SerializedName("expires_at")
        private String expiresAt;
    
        // getters, setters, toString
    }
    

    And example how to parse your JSON:

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.google.gson.annotations.SerializedName;
    
    import java.io.File;
    import java.io.FileReader;
    import java.math.BigDecimal;
    import java.util.HashMap;
    import java.util.Map;
    
    public class GsonApp {
    
        public static void main(String[] args) throws Exception {
            File jsonFile = new File("./resource/test.json").getAbsoluteFile();
    
            Gson gson = new GsonBuilder().create();
    
            FlightResponse flightResponse = gson.fromJson(new FileReader(jsonFile), FlightResponse.class);
    
            flightResponse.getFlatData().forEach((k, v) -> {
                System.out.println(k + " => " + v);
            });
        }
    }
    

    Above code prints:

    0 => Flight{price=153, airline='LO', flightNumber=678, departureAt='2019-08-05T17:40:00Z', returnAt='2019-08-20T14:35:00Z', expiresAt='2019-05-24T20:55:02Z'}
    1 => Flight{price=126, airline='A3', flightNumber=881, departureAt='2019-11-21T11:00:00Z', returnAt='2019-11-26T16:05:00Z', expiresAt='2019-05-27T13:39:23Z'}
    2 => Flight{price=171, airline='KL', flightNumber=900, departureAt='2019-09-12T02:40:00Z', returnAt='2019-09-18T17:30:00Z', expiresAt='2019-05-27T10:40:40Z'}
    3 => Flight{price=235, airline='B2', flightNumber=972, departureAt='2019-06-12T07:20:00Z', returnAt='2019-06-18T17:30:00Z', expiresAt='2019-05-26T12:31:22Z'}
    4 => Flight{price=596, airline='TK', flightNumber=422, departureAt='2019-06-20T00:10:00Z', returnAt='2019-06-24T13:05:00Z', expiresAt='2019-05-26T08:08:21Z'}
    

    See also: