将复杂映射类型API响应映射到Java POJO
这是我的API响应,这里的响应是映射对象而不是Json将复杂映射类型API响应映射到Java POJO,java,collections,Java,Collections,这是我的API响应,这里的响应是映射对象而不是Json { "staticResponses": [ { "code": { "id": "someId", "value": "44343567" }, "staticAttributes": [ { "id": "SEC_GUAR", "value": "someValue4" },
{
"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
我需要将数据映射到的Pojo
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class RatingCompositionModel implements CompositionModel {
private List<RatingModel> ratings;
}
我编写的代码也实现了同样的功能
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;
}
private CompositionModel mapResponseToObject(LinkedHashMap responseBody){
RatingCompositionModel RatingCompositionModel=新的RatingCompositionModel();
List ratingModelList=新建ArrayList();
List responseObjectList=(List)responseBody.get(“staticResponses”);
if(null!=responseObjectList&!responseObjectList.isEmpty()){
responseObjectList.forEach(responseObject->{
List staticAttributes=(List)responseObject.get(“staticAttributes”);
if(null!=staticAttributes&!staticAttributes.isEmpty()){
RatingModel RatingModel=新的RatingModel();
staticAttributes.forEach(staticAttribute->{
if(((字符串)staticAttribute.get(“id”)).equals(“SEC_GUAR”)){
ratingModel.setSecurityCurrency((字符串)staticAttribute.get(“值”);
}
//如果在这里还有更多。。。
});
ratingModelList.add(ratingModel);
}
});
}
ratingCompositionModel.setRatings(评级模型列表);
收益率构成模型;
}
所以这里的问题是我必须使用的if-else块的数量,目前我有大约50个字段需要从API响应中提取,需要映射到POJO中的相应字段,因此我的方法必须使用50个if-else条件,并且在将来,如果POJO中有任何更改,则需要添加更多字段(可能性很高)我必须添加更多if-else块。
这里还值得注意的是,我无法更改API响应中字段的名称以将其与我的POJO匹配,因为这是我无法控制的第三方API
这里寻找更动态的解决方案,以避免if-else阻塞,并有效地处理将来的任何更改。您可以使用Gson库提供的@SerializedName注释对类的字段进行注释。您可以在下面找到一个示例。使用此库转换为json或从json转换为json非常方便
您不需要使用if-else条件,只需迭代
staticAttributes
并将它们存储在映射中
完成后,您就可以使用ObjectMapper
的convertValue
api将这个映射
对象直接映射到您的POJO类
FinalPojo readValue = objectMapper.convertValue(collect, FinalPojo.class);
但是您需要告诉Jackson映射图中的哪个键要映射到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;
}
在这里,我想不能使用Gson的@SerializedName,因为我的API响应不是json,而且我有嵌套响应,其中键始终是POJO中所有对应字段的id和值,任何示例都会有所帮助。感谢这个答案,但有没有一种方法可以在不修改现有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;
}