Vishakha Lall
Vishakha Lall

Reputation: 1314

Gson fromJson returning null object

I am frustrated with a silly error, I am trying to parse a json to my desired class but somehow it is returning a null object. My json is as follows:

{
  "service_requests": [
    {
      "serviceRequestItems": [
        {
          "entityId": "688210985",
          "entityType": "wh_inventory",
          "sourceArea": "transient",
          "destinationArea": "store",
          "srItemLabels": [
            
          ],
          "attributes": [
            {
              "name": "wid",
              "value": "test"
            }
          ]
        }
      ]
    }
  ]
}

This is being returned from an API call and I have validated this from the debug mode of my IDE. Following are my classes

@JsonIgnoreProperties(ignoreUnknown = true)
public class PayloadDTO {

    @JsonProperty("service_requests")
    List<SRCreationRequest> serviceRequests;

    public List<SRCreationRequest> getServiceRequests() {
        return serviceRequests;
    }

    public void setServiceRequests(List<SRCreationRequest> serviceRequests) {
        this.serviceRequests = serviceRequests;
    }

    @Override
    public String toString() {

        return "PayloadDTO{" + "service_requests=" + serviceRequests + '}';
    }
}
public class SRCreationRequest {

    private List<SRItemCreationRequest> serviceRequestItems;

    public List<SRItemCreationRequest> getServiceRequestItems() {

        return serviceRequestItems;
    }

    public void setServiceRequestItems(List<SRItemCreationRequest> serviceRequestItems) {

        this.serviceRequestItems = serviceRequestItems;
    }

    @Override
    public String toString() {

        return "SRCreationRequest{" + "serviceRequestItems=" + serviceRequestItems + ", tenantId='" + tenantId + '\''
                + ", clientId='" + clientId + '\'' + ", facilityId='" + facilityId + '\'' + ", context='" + context + '\''
                + ", idempotenceKey='" + idempotenceKey + '\'' + ", shardInfo=" + shardInfo + ", apiContext='" + apiContext
                + '\'' + '}';
    }
}
public class SRItemCreationRequest {

    private String entityId;
    private String entityType;
    private SRItemContainer sourceContainer;
    private String sourceArea;
    private SRItemContainer destinationContainer;
    private String destinationArea;
    private List<SRItemLabel> srItemLabels;
    private String groupId;
    private List<SRItemAttribute> attributes;

    public String getEntityId() {

        return entityId;
    }

    public void setEntityId(String entityId) {

        this.entityId = entityId;
    }

    public String getEntityType() {

        return entityType;
    }

    public void setEntityType(String entityType) {

        this.entityType = entityType;
    }

    public SRItemContainer getSourceContainer() {

        return sourceContainer;
    }

    public void setSourceContainer(SRItemContainer sourceContainer) {

        this.sourceContainer = sourceContainer;
    }

    public String getSourceArea() {

        return sourceArea;
    }

    public void setSourceArea(String sourceArea) {

        this.sourceArea = sourceArea;
    }

    public SRItemContainer getDestinationContainer() {

        return destinationContainer;
    }

    public void setDestinationContainer(SRItemContainer destinationContainer) {

        this.destinationContainer = destinationContainer;
    }

    public String getDestinationArea() {

        return destinationArea;
    }

    public void setDestinationArea(String destinationArea) {

        this.destinationArea = destinationArea;
    }

    public List<SRItemLabel> getSrItemLabels() {

        return srItemLabels;
    }

    public void setSrItemLabels(List<SRItemLabel> srItemLabels) {

        this.srItemLabels = srItemLabels;
    }

    public String getGroupId() {

        return groupId;
    }

    public void setGroupId(String groupId) {

        this.groupId = groupId;
    }

    public List<SRItemAttribute> getAttributes() {

        return attributes;
    }

    public void setAttributes(List<SRItemAttribute> attributes) {

        this.attributes = attributes;
    }

    @Override
    public String toString() {

        return "SRItemCreationRequest{" + "entityId='" + entityId + '\'' + ", entityType='" + entityType + '\''
                + ", sourceContainer=" + sourceContainer + ", sourceArea='" + sourceArea + '\'' + ", destinationContainer="
                + destinationContainer + ", destinationArea='" + destinationArea + '\'' + ", srItemLabels=" + srItemLabels
                + ", groupId='" + groupId + '\'' + ", attributes=" + attributes + '}';
    }
}

Both SRItemAttribute and SRItemLabel look like this

@ApiModel
public class SRItemAttribute {
    @ApiModelProperty(name = "name", value = "Attribute name")
    @JsonProperty(value = "name")
    @NotEmpty(message = "{sr.attr.name.notnull}")
    private String name;

    @ApiModelProperty(name = "value", value = "Attribute value")
    @JsonProperty(value = "value")
    @NotEmpty(message = "{sr.attr.value.notnull}")
    private String value;

    public SRItemAttribute() {

    }

    public SRItemAttribute(String name, String value) {

        this.name = name;
        this.value = value;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {

        this.name = name;
    }

    public String getValue() {

        return value;
    }

    public void setValue(String value) {

        this.value = value;
    }

    @Override
    public String toString() {

        return "SRAttribute{" + "name='" + name + '\'' + ", value='" + value + '\'' + '}';
    }
}

and since I'm not using the SRItemContainer and ignoring unknown properties, I'm assuming that should not be a problem. and I'm parsing as follows

Gson gson = new Gson();
        String jsonInString = gson.toJson(//getting from API here);
        LOGGER.debug("jsonInString "+jsonInString); //as above
        PayloadDTO serviceRequests = gson.fromJson(jsonInString, PayloadDTO.class);

Can anyone see where I'm going wrong?

Upvotes: 1

Views: 2678

Answers (1)

Kidus Tekeste
Kidus Tekeste

Reputation: 661

Have you checked your second class called SRCreationRequest. Doesn't it not require to have annotation as well? for this part: private List<SRItemCreationRequest> serviceRequestItems;

I am thinking you need to add annotation for GSON to read it as an attribute of the API response model. Something like this on the attribute @JsonProperty("serviceRequestItems")

For such kind of model generation I always use online tools. doing it manually causes a mistake somewhere and its hard to get for a complex model.

here check this site: http://www.jsonschema2pojo.org/

I have generated your json response to a java class pojo class.

Here is the result:

for PayloadDTO :

public class PayloadDTO {

    @SerializedName("service_requests")
    @Expose
    private List<ServiceRequest> serviceRequests = null;

    public List<ServiceRequest> getServiceRequests() {
        return serviceRequests;
    }

    public void setServiceRequests(List<ServiceRequest> serviceRequests) {
        this.serviceRequests = serviceRequests;
    }

}

for ServiceRequest :

public class ServiceRequest {

    @SerializedName("serviceRequestItems")
    @Expose
    private List<ServiceRequestItem> serviceRequestItems = null;

    public List<ServiceRequestItem> getServiceRequestItems() {
        return serviceRequestItems;
    }

    public void setServiceRequestItems(List<ServiceRequestItem> serviceRequestItems) {
        this.serviceRequestItems = serviceRequestItems;
    }

}

for ServiceRequestItem:


public class ServiceRequestItem {

    @SerializedName("entityId")
    @Expose
    private String entityId;
    @SerializedName("entityType")
    @Expose
    private String entityType;
    @SerializedName("sourceArea")
    @Expose
    private String sourceArea;
    @SerializedName("destinationArea")
    @Expose
    private String destinationArea;
    @SerializedName("srItemLabels")
    @Expose
    private List<Object> srItemLabels = null;
    @SerializedName("attributes")
    @Expose
    private List<Attribute> attributes = null;

    public String getEntityId() {
        return entityId;
    }

    public void setEntityId(String entityId) {
        this.entityId = entityId;
    }

    public String getEntityType() {
        return entityType;
    }

    public void setEntityType(String entityType) {
        this.entityType = entityType;
    }

    public String getSourceArea() {
        return sourceArea;
    }

    public void setSourceArea(String sourceArea) {
        this.sourceArea = sourceArea;
    }

    public String getDestinationArea() {
        return destinationArea;
    }

    public void setDestinationArea(String destinationArea) {
        this.destinationArea = destinationArea;
    }

    public List<Object> getSrItemLabels() {
        return srItemLabels;
    }

    public void setSrItemLabels(List<Object> srItemLabels) {
        this.srItemLabels = srItemLabels;
    }

    public List<Attribute> getAttributes() {
        return attributes;
    }

    public void setAttributes(List<Attribute> attributes) {
        this.attributes = attributes;
    }

}

and lastly for the attribute models:

public class Attribute {

    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("value")
    @Expose
    private String value;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

The annotations I used might be a little different from that you used but it will generate the correct according to your setting on the right side options.

Here is my config for your model in site:

enter image description here

Upvotes: 2

Related Questions