'Convert of JSON to a java object and a list of java objects

I get this JSONObject response from an API

    {
  "meta": {
    "code": 200
  },
  "data": {
    "tracking": {
      "id": "lk46hwgbadfqcl2fyacyw00q",
      "created_at": "2022-04-26T09:33:13+00:00",
      "updated_at": "2022-04-26T09:33:14+00:00",
      "last_updated_at": "2022-04-26T09:33:14+00:00",
      "tracking_number": "1Z965EW40228937186",
      "slug": "ups",
      "active": false,
      "android": [],
      "custom_fields": null,
      "customer_name": null,
      "delivery_time": 20,
      "destination_country_iso3": "USA",
      "courier_destination_country_iso3": "USA",
      "emails": [],
      "expected_delivery": null,
      "ios": [],
      "note": null,
      "order_id": null,
      "order_id_path": null,
      "order_date": null,
      "origin_country_iso3": "USA",
      "shipment_package_count": null,
      "shipment_pickup_date": "2022-03-28T19:45:12-07:00",
      "shipment_delivery_date": "2022-04-16T16:04:15",
      "shipment_type": "UPS 2nd Day Air®",
      "shipment_weight": 15.8,
      "shipment_weight_unit": "lb",
      "signed_by": "DRIVER RELEASE",
      "smses": [],
      "source": "api",
      "tag": "Delivered",
      "subtag": "Delivered_001",
      "subtag_message": "Delivered",
      "title": "dd",
      "tracked_count": 1,
      "last_mile_tracking_supported": true,
      "language": null,
      "unique_token": "deprecated",
      "checkpoints": [
        {
          "slug": "ups",
          "city": null,
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "US, United States",
          "country_name": "USA",
          "message": "Shipper created a label, UPS has not received the package yet.",
          "country_iso3": "USA",
          "tag": "InfoReceived",
          "subtag": "InfoReceived_001",
          "subtag_message": "Info Received",
          "checkpoint_time": "2022-03-28T15:55:14-07:00",
          "coordinates": [],
          "state": null,
          "zip": null,
          "raw_tag": "MP"
        },
        {
          "slug": "ups",
          "city": "Goodyear",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Goodyear, AZ, US, United States",
          "country_name": "USA",
          "message": "Origin Scan",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_002",
          "subtag_message": "Acceptance scan",
          "checkpoint_time": "2022-03-28T19:45:12-07:00",
          "coordinates": [],
          "state": "AZ",
          "zip": null,
          "raw_tag": "OR"
        },
        {
          "slug": "ups",
          "city": "Goodyear",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Goodyear, AZ, US, United States",
          "country_name": "USA",
          "message": "Departed from Facility",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_007",
          "subtag_message": "Departure Scan",
          "checkpoint_time": "2022-03-29T00:38:00-07:00",
          "coordinates": [],
          "state": "AZ",
          "zip": null,
          "raw_tag": "DP"
        },
        {
          "slug": "ups",
          "city": "Phoenix",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Phoenix, AZ, US, United States",
          "country_name": "USA",
          "message": "Arrived at Facility",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_003",
          "subtag_message": "Arrival scan",
          "checkpoint_time": "2022-03-29T01:18:00-07:00",
          "coordinates": [],
          "state": "AZ",
          "zip": null,
          "raw_tag": "AR"
        },
        {
          "slug": "ups",
          "city": "Phoenix",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Phoenix, AZ, US, United States",
          "country_name": "USA",
          "message": "Departed from Facility",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_007",
          "subtag_message": "Departure Scan",
          "checkpoint_time": "2022-03-29T05:43:00-07:00",
          "coordinates": [],
          "state": "AZ",
          "zip": null,
          "raw_tag": "DP"
        },
        {
          "slug": "ups",
          "city": "Philadelphia",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Philadelphia, PA, US, United States",
          "country_name": "USA",
          "message": "Arrived at Facility",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_003",
          "subtag_message": "Arrival scan",
          "checkpoint_time": "2022-03-29T12:54:00-04:00",
          "coordinates": [],
          "state": "PA",
          "zip": null,
          "raw_tag": "AR"
        },
        {
          "slug": "ups",
          "city": "Philadelphia",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Philadelphia, PA, US, United States",
          "country_name": "USA",
          "message": "Departed from Facility",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_007",
          "subtag_message": "Departure Scan",
          "checkpoint_time": "2022-03-30T01:17:00-04:00",
          "coordinates": [],
          "state": "PA",
          "zip": null,
          "raw_tag": "DP"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Arrived at Facility",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_003",
          "subtag_message": "Arrival scan",
          "checkpoint_time": "2022-03-30T04:03:00-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "AR"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Processing at UPS Facility",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_001",
          "subtag_message": "In Transit",
          "checkpoint_time": "2022-03-30T06:20:05-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "YP"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Out For Delivery Today",
          "country_iso3": "USA",
          "tag": "OutForDelivery",
          "subtag": "OutForDelivery_001",
          "subtag_message": "Out for Delivery",
          "checkpoint_time": "2022-03-30T09:13:00-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "OT"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "The receiver was not available for delivery. We'll make a second attempt the next business day.",
          "country_iso3": "USA",
          "tag": "AttemptFail",
          "subtag": "AttemptFail_002",
          "subtag_message": "Addreesee not available",
          "checkpoint_time": "2022-03-30T19:55:20-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "48"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Out For Delivery Today",
          "country_iso3": "USA",
          "tag": "OutForDelivery",
          "subtag": "OutForDelivery_001",
          "subtag_message": "Out for Delivery",
          "checkpoint_time": "2022-03-31T09:03:56-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "OT"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "The receiver was not available for delivery. We'll make a second attempt the next business day.",
          "country_iso3": "USA",
          "tag": "AttemptFail",
          "subtag": "AttemptFail_002",
          "subtag_message": "Addreesee not available",
          "checkpoint_time": "2022-03-31T20:17:04-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "48"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Out For Delivery Today",
          "country_iso3": "USA",
          "tag": "OutForDelivery",
          "subtag": "OutForDelivery_001",
          "subtag_message": "Out for Delivery",
          "checkpoint_time": "2022-04-01T09:33:30-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "OT"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "The receiver was not available for delivery. We'll make a second attempt the next business day.",
          "country_iso3": "USA",
          "tag": "AttemptFail",
          "subtag": "AttemptFail_002",
          "subtag_message": "Addreesee not available",
          "checkpoint_time": "2022-04-01T18:17:11-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "48"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Processing at UPS Facility",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_001",
          "subtag_message": "In Transit",
          "checkpoint_time": "2022-04-02T03:34:21-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "YP"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Loaded on Delivery Vehicle",
          "country_iso3": "USA",
          "tag": "OutForDelivery",
          "subtag": "OutForDelivery_001",
          "subtag_message": "Out for Delivery",
          "checkpoint_time": "2022-04-02T03:49:53-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "OF"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Out For Delivery Today",
          "country_iso3": "USA",
          "tag": "OutForDelivery",
          "subtag": "OutForDelivery_001",
          "subtag_message": "Out for Delivery",
          "checkpoint_time": "2022-04-02T09:49:40-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "OT"
        },
        {
          "slug": "ups",
          "city": "Landover",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Landover, MD, US, United States",
          "country_name": "USA",
          "message": "Package was driver released",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_001",
          "subtag_message": "In Transit",
          "checkpoint_time": "2022-04-02T17:00:44-04:00",
          "coordinates": [],
          "state": "MD",
          "zip": null,
          "raw_tag": "FS"
        },
        {
          "slug": "ups",
          "city": "Bronx",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Bronx, NY, US, United States",
          "country_name": "USA",
          "message": "The receiver refused, the package appeared to be damaged. UPS will notify the sender with the details.",
          "country_iso3": "USA",
          "tag": "Exception",
          "subtag": "Exception_003",
          "subtag_message": "Customer refused delivery",
          "checkpoint_time": "2022-04-14T15:08:16-04:00",
          "coordinates": [],
          "state": "NY",
          "zip": null,
          "raw_tag": "KQ"
        },
        {
          "slug": "ups",
          "city": "Great Falls",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "Great Falls, MT, US, United States",
          "country_name": "USA",
          "message": "Package was driver released",
          "country_iso3": "USA",
          "tag": "InTransit",
          "subtag": "InTransit_001",
          "subtag_message": "In Transit",
          "checkpoint_time": "2022-04-15T16:04:15-06:00",
          "coordinates": [],
          "state": "MT",
          "zip": null,
          "raw_tag": "FS"
        },
        {
          "slug": "ups",
          "city": "GOODYEAR",
          "created_at": "2022-04-26T09:33:14+00:00",
          "location": "GOODYEAR, AZ, US, United States",
          "country_name": "USA",
          "message": "DELIVERED",
          "country_iso3": "USA",
          "tag": "Delivered",
          "subtag": "Delivered_001",
          "subtag_message": "Delivered",
          "checkpoint_time": "2022-04-16T16:04:15-06:00",
          "coordinates": [],
          "state": "AZ",
          "zip": null,
          "raw_tag": "FS"
        }
      ],
      "subscribed_smses": [],
      "subscribed_emails": [],
      "return_to_sender": false,
      "order_promised_delivery_date": null,
      "delivery_type": null,
      "pickup_location": null,
      "pickup_note": null,
      "courier_tracking_link": "https://www.ups.com/track?loc=en_US&tracknum=1Z965EW40228937186&requester=WT/trackdetails",
      "first_attempted_at": "2022-03-30T19:55:20-04:00",
      "courier_redirect_link": "https://www.ups.com/track?loc=en_US&tracknum=1Z965EW40228937186&requester=WT/trackdetails",
      "order_tags": [],
      "order_number": null,
      "aftership_estimated_delivery_date": null,
      "on_time_status": null,
      "on_time_difference": null,
      "tracking_account_number": null,
      "tracking_origin_country": null,
      "tracking_destination_country": null,
      "tracking_key": null,
      "tracking_postal_code": null,
      "tracking_ship_date": null,
      "tracking_state": null
    }
  }
}

I need to put the data from the JSONObject into 2 Java objects.

Some of data under "data": { "tracking": { goes into the Java object Tracking ( matching variable names ) and the list of checkpoints + tracking_number ( in each checkpoint object ) goes in the java object Checkpoint

Tracking class

    @PrimaryKey
@NonNull
@ColumnInfo(name = "Tracking_number")
public String trackingNumber;

/**Unique code of each courier. If you do not specify a slug, Aftership will automatically detect
 * the courier based on the tracking number format and your selected couriers*/
@ColumnInfo(name = "slug")
public String slug;

/** Memo of the tracking. Default value as trackingNumber */
@ColumnInfo(name = "memo")
public String memo;

/** Customer name of the tracking. */
@ColumnInfo(name = "Customer_Name")
public String customerName;

/** ISO Alpha-3(three letters)to specify the destination of the shipment.
 * If you use postal service to send international shipments, AfterShip will automatically
 * get tracking results at destination courier as well (e.g. USPS for USA). */
@ColumnInfo(name = "Destination_Country")
public String destinationCountryISO3;

/**  Origin country of the tracking. ISO Alpha-3 */
@ColumnInfo(name = "Origin_Country")
public String originCountryISO3;

/** fields informed by Aftership API*/

/**  Date and time of the tracking created. */
@ColumnInfo(name = "Created_date")
public String createdAt;

/** Date and time of the tracking last updated. */
@ColumnInfo(name = "Last_updated")
public String updatedAt;

/** Whether or not AfterShip will continue tracking the shipments.
 * Value is `false` when status is `Delivered` or `Expired`. */
@ColumnInfo(name = "Active_status")
public boolean active;

/** Expected delivery date (if any). */
@ColumnInfo(name = "Expected_delivery")
public String expectedDelivery;

/**  Number Number of packages under the tracking. */
@ColumnInfo(name = "Package_count")
public int shipmentPackageCount;

/** Shipment type provided by carrier (if any). */
@ColumnInfo(name = "Shipment_type")
public String shipmentType;

/** Signed by information for delivered shipment (if any). */
@ColumnInfo(name = "Signed_by")
public String signedBy;

/** Current status of tracking. */
@ColumnInfo(name = "Tag")
public String tag;

/**  Number of attempts AfterShip tracks at courier's system. */
@ColumnInfo(name = "Tracked_count")
public int trackedCount;

/**Tracking postal code tracking_postal_code*/
@ColumnInfo(name = "Tracking_postal_code")
public String trackingPostalCode;

/**Tracking ship date tracking_ship_date*/
@ColumnInfo(name = "Tracking_ship_date")
public String trackingShipDate;

Checkpoint class

 @PrimaryKey
@ColumnInfo(name = "Tracking_number")
@NonNull
public String trackingNumber;

/** Date and time of the tracking created. */
@ColumnInfo(name = "Date_created")
public String createdAt;

/** Date and time of the checkpoint, provided by courier. Value may be:
 Empty String,
 YYYY-MM-DD,
 YYYY-MM-DDTHH:MM:SS, or
 YYYY-MM-DDTHH:MM:SS+TIMEZONE */
@ColumnInfo(name = "Checkpoint_time")
public String checkpointTime;

/** Location info (if any) */
@ColumnInfo(name = "City")
public String city;

/** Country ISO Alpha-3 (three letters) of the checkpoint */
@ColumnInfo(name = "Country_ISO")
public String countryISO3;

/** Country name of the checkpoint, may also contain other location info. */
@ColumnInfo(name = "Country_name")
public String countryName;

/** Checkpoint message */
@ColumnInfo(name = "Message")
public String message;

/** Location info (if any) */
@ColumnInfo(name = "State")
public String state;

/** Status of the checkpoint */
@ColumnInfo(name = "tag")
public String tag;

/** Location info (if any) */
@ColumnInfo(name = "Postal_code")
public String zip;

This is what I currently have to convert the JSONObject to Tracking obj but it converts the entirety of the JSONObject while I only need the data fields that exist in the Tracking class. For checkpoints, I need the list of checkpoint(s) from the JSONObject to be converted to a list of checkpoint objects.

 Gson gson = new Gson();
        Tracking tracking = gson.fromJson(trackingJSON.getJSONObject("tracking").toString(), Tracking.class);


Solution 1:[1]

Since your trackingJSON apparently already contains the parsed JSON in DOM form, it might be easiest to manually extract the checkpoints property, and then let Gson deserialize that separately, for example:

JSONObject trackingJson = trackingJSON.getJSONObject("tracking");
// Uses `remove` to avoid unnecessary conversion when calling `trackingData.toString()`
JSONArray checkpointsJson = (JSONArray) trackingData.remove("checkpoints");

Tracking tracking = gson.fromJson(trackingJson.toString(), Tracking.class);
List<Checkpoint> checkpoints = gson.fromJson(checkpointsJson.toString(),
    new TypeToken<List<Checkpoint>>() {}.getType());

// Manually set the tracking number
checkpoints.forEach(c -> c.trackingNumber = tracking.trackingNumber);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Marcono1234