Сопоставленный API-интерфейс типа сложной карты для ответа Java POJO - PullRequest
0 голосов
/ 21 февраля 2020

Вот мой ответ API, здесь ответ приходит как объект карты, а не 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 на эквивалентное отображение поля Pojo

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 что мне нужно сопоставить данные

@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 
}

Код, который я написал для достижения того же

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;
 }

Так вот проблема заключается в количестве блоков if-else, которые я должен использовать, в настоящее время у меня есть около 50 полей, которые мне нужно извлечь из ответа API, и мне нужно сопоставить соответствующие поля в моем POJO, поэтому при моем подходе я должен использовать 50 условий if-else и в будущем, если в моем POJO произойдут какие-либо изменения, такие как добавление еще нескольких полей (что имеет высокую вероятность), я должен добавить еще блок if-else. Также стоит отметить, что я не могу изменить имя полей в ответе API, чтобы оно совпадало с моим POJO, потому что это какой-то сторонний API, который не находится под моим контролем.

Здесь ищется более динамичное c решение, позволяющее избежать блока if-else, а также эффективно обрабатывать любые будущие изменения.

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

вам не нужно иметь условия if-else, просто переберите staticAttributes и сохраните их в Map, и как только это будет сделано, вы можете напрямую отобразить этот объект Map в свой класс POJO, используя ObjectMapper s convertValue api.

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

Но вам нужно будет сказать Джексону, что какой ключ на карте должен быть сопоставлен с тем или иным полем в вашем POJO. И вы можете использовать для этого аннотацию @JsonProperty.

Ниже приведен пример класса POJO

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;
}
0 голосов
/ 21 февраля 2020

Вы можете просто аннотировать поля класса аннотацией @SerializedName, предоставленной библиотекой Gson. Вы можете найти пример ниже. Это действительно удобно использовать этот librart для преобразования в / из json.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...