Home » Java » collections – Mapped Complex Map Type API Response To Java POJO-Exceptionshub

collections – Mapped Complex Map Type API Response To Java POJO-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

Here is my API Response, here the response is coming as Map object not Json.

 {
  "staticResponses": [
    {
      "code": {
        "id": "someId",
        "value": "44343567"
      },
      "staticAttributes": [
        {
          "id": "SEC_GUAR",
          "value": "someValue4"
        },
        {
          "id": "FIN_BOND_TYPE",
          "value": ""
        },
        {
          "id": "SEC_ISSER_ID",
          "value": "someValue5"
        },
        {
          "id": "SEC_ISSE_CRNCY",
          "value": "someValue6"
        }
        //Here more objects with id and value(same as above) which needs to be mapped to corresponding fields of RatingModel Pojo.   
      ]
    }
  ]
}

API Response to equivalent Pojo field mapping

Keys Comming In API Response        Corresponding Field Name in Model            
SEC_GUAR                            guarantor
FIN_BOND_TYPE                       covered
SEC_ISSER_ID                        issuerId
SEC_ISSE_CRNCY                      securityCurrency

My Pojo to which I need to mapped the data

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class RatingCompositionModel implements CompositionModel {
   private List<RatingModel> ratings;
}

RatingModel.java

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class RatingModel implements CompositionModel, Serializable {

    private static final long serialVersionUID = -8447345872052120852L;

    private String securityCurrency;
    private String covered;
    private String guarantor;
    private String issuerId;
    //here renaming fields 
}

Code that I have written to achieve the same

private CompositionModel mapResponseToObject(LinkedHashMap responseBody) {
        RatingCompositionModel ratingCompositionModel = new RatingCompositionModel();
        List<RatingModel> ratingModelList = new ArrayList<>();
        List<LinkedHashMap> responseObjectList = (List<LinkedHashMap>) responseBody.get("staticResponses");
        if( null != responseObjectList && !responseObjectList.isEmpty() ) {
            responseObjectList.forEach(responseObject -> {
                List<LinkedHashMap> staticAttributes = (List<LinkedHashMap>)responseObject.get("staticAttributes");
                if( null != staticAttributes && !staticAttributes.isEmpty()) {
                    RatingModel ratingModel = new RatingModel();
                    staticAttributes.forEach(staticAttribute -> {
                        if( ((String)staticAttribute.get("id")).equals("SEC_GUAR") ) {
                            ratingModel.setSecurityCurrency((String)staticAttribute.get("value"));
                        }
                        // more else if here...
                    });
                    ratingModelList.add(ratingModel);
                }
            });
        }
        ratingCompositionModel.setRatings(ratingModelList);
        return ratingCompositionModel;
 }

So here the problem is number of if-else block that I have to used,currently I have around 50 fields which I need to extract from the API Response and need to mapped to the corresponding fields in my POJO, so with my approach I have to use 50 if-else conditions and in future, if any change in my POJO like addition of some more fields(which has a high possibility) I have to add more if-else block.
Also worth noting here I cannot change the name of the fields in API response to match it with my POJO because this is some third party API not in my control.

Here looking for more dynamic solution to avoid if-else block as well to efficiently handle any future changes.

How to&Answers:

you don’t need to have if-else conditions their, just iterate through staticAttributes and store them in a Map and once that is done, you can directly map this Map object to your POJO class using ObjectMapper‘s convertValue api.

FinalPojo readValue = objectMapper.convertValue(collect, FinalPojo.class);

But you would need to tell Jackson that which key in the map is to be mapped to what field in your POJO. And you can use @JsonProperty annotation for that.

Below is the sample POJO class

import com.fasterxml.jackson.annotation.JsonProperty;

public class FinalPojo {

  @JsonProperty("SEC_GUAR")
  private String guarantor;

  @JsonProperty("FIN_BOND_TYPE")
  private String covered;

  @JsonProperty("SEC_ISSER_ID")
  private String issuerId;

  @JsonProperty("SEC_ISSE_CRNCY")
  private String securityCurrency;
}

Answer:

you can simply annotate the fields of the class with @SerializedName annotation given by Gson library. you can find an example below. Its really conveniet to use this librart to convert to/from json.

https://www.tutorialspoint.com/what-to-use-serializedname-annotation-using-gson-in-java