如何在 java 中解析具有动态 属性 名称的 json?
How to parse a json with dynamic property name in java?
我需要在我的代码中使用和解析来自 CRM 系统的传入 json。我使用 RestTemplate 来做到这一点。因此,CRM 系统的响应如下所示。
{ "GvyArEFkg6JX6wI": {
"entityId": "GvyArEFkg6JX6wI",
"mergePolicy": {
"id": "9245a39d-fe1a-4b33-acab-9bc5cbabf37c"
}
}
}
现在的问题是动态的 属性 名称(在本例中为“GvyArEFkg6JX6wI”),在下一个响应中它将是另一个字符串。在这种情况下,我该如何解析这个 json 因为这不是固定的?我尝试使用 jsonGetter
但它只是将它包裹在另一个块周围,仍然没有解决解析响应的问题。
AdobeResponseDto.class
@Builder
@ToString
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
public class AdobeResponseDto {
public Map<String, AdobeResponseFinal> adobeResponseWrapper = new HashMap<>();
@JsonAnySetter
public void setAdobeResponseWrapper(String name, AdobeResponseFinal value) {
adobeResponseWrapper.put(name, value);
}
@JsonAnyGetter
public Map<String, AdobeResponseFinal> getAdobeResponseWrapper() {
return adobeResponseWrapper;
}
}
AdobeResponseFinal.class
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AdobeResponseFinal {
public String entityId;
public MergePolicy mergePolicy;
}
我是这样调用服务的:
final ResponseEntity<AdobeResponseDto> finalResponse;
finalResponse = aepClient.exchange(uri,HttpMethod.GET,entity,AdobeResponseDto.class);
final AdobeResponseDto body = finalResponse.getBody();
if(ObjectUtils.isNotEmpty(body)){
return body;
}
但是通过这种方式,我得到的响应是
{
"adobeResponseWrapper": {
"GvyArEFkg6JX6wI": {
"entityId": "GvyArEFkg6JX6wI",
"mergePolicy": {
"id": "9245a39d-fe1a-4b33-acab-9bc5cbabf37c"
}
}
如果您只想获取动态字段名称的值(例如,在您的情况下为“GvyArEFkg6JX6wI”),您可以将响应主体反序列化为 Map
然后遍历其值,如下所示:
ResponseEntity<String> finalResponse = aepClient.exchange(uri, HttpMethod.GET, entity, String.class);
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> result = objectMapper.readValue(finalResponse.getBody(), Map.class);
result.values().forEach(System.out::println);
控制台输出:
{entityId=GvyArEFkg6JX6wI, mergePolicy={id=9245a39d-fe1a-4b33-acab-9bc5cbabf37c}}
并且如果你想将响应主体反序列化到你的DTO(我假设只有ONE根级别属性),你可以修改DTO喜欢:
public class AdobeResponseDto {
private AdobeResponseFinal adobeResponseFinal;
@JsonAnySetter
public void setAdobeResponseFinal(String name, AdobeResponseFinal value) {
adobeResponseFinal = value;
}
@JsonAnyGetter
public AdobeResponseFinal getAdobeResponseFinal() {
return adobeResponseFinal;
}
}
那么你可以得到类似如下的结果:
ResponseEntity<String> finalResponse = aepClient.exchange(uri, HttpMethod.GET, entity, String.class);
AdobeResponseDto adobeResponseDto = objectMapper.readValue(finalResponse.getBody(), AdobeResponseDto.class);
System.out.println(adobeResponseDto.getAdobeResponseFinal().toString());
控制台输出:
AdobeResponseFinal{entityId='GvyArEFkg6JX6wI', mergePolicy=MergePolicy{id='9245a39d-fe1a-4b33-acab-9bc5cbabf37c'}}
我需要在我的代码中使用和解析来自 CRM 系统的传入 json。我使用 RestTemplate 来做到这一点。因此,CRM 系统的响应如下所示。
{ "GvyArEFkg6JX6wI": {
"entityId": "GvyArEFkg6JX6wI",
"mergePolicy": {
"id": "9245a39d-fe1a-4b33-acab-9bc5cbabf37c"
}
}
}
现在的问题是动态的 属性 名称(在本例中为“GvyArEFkg6JX6wI”),在下一个响应中它将是另一个字符串。在这种情况下,我该如何解析这个 json 因为这不是固定的?我尝试使用 jsonGetter
但它只是将它包裹在另一个块周围,仍然没有解决解析响应的问题。
AdobeResponseDto.class
@Builder
@ToString
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
public class AdobeResponseDto {
public Map<String, AdobeResponseFinal> adobeResponseWrapper = new HashMap<>();
@JsonAnySetter
public void setAdobeResponseWrapper(String name, AdobeResponseFinal value) {
adobeResponseWrapper.put(name, value);
}
@JsonAnyGetter
public Map<String, AdobeResponseFinal> getAdobeResponseWrapper() {
return adobeResponseWrapper;
}
}
AdobeResponseFinal.class
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AdobeResponseFinal {
public String entityId;
public MergePolicy mergePolicy;
}
我是这样调用服务的:
final ResponseEntity<AdobeResponseDto> finalResponse;
finalResponse = aepClient.exchange(uri,HttpMethod.GET,entity,AdobeResponseDto.class);
final AdobeResponseDto body = finalResponse.getBody();
if(ObjectUtils.isNotEmpty(body)){
return body;
}
但是通过这种方式,我得到的响应是
{
"adobeResponseWrapper": {
"GvyArEFkg6JX6wI": {
"entityId": "GvyArEFkg6JX6wI",
"mergePolicy": {
"id": "9245a39d-fe1a-4b33-acab-9bc5cbabf37c"
}
}
如果您只想获取动态字段名称的值(例如,在您的情况下为“GvyArEFkg6JX6wI”),您可以将响应主体反序列化为 Map
然后遍历其值,如下所示:
ResponseEntity<String> finalResponse = aepClient.exchange(uri, HttpMethod.GET, entity, String.class);
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> result = objectMapper.readValue(finalResponse.getBody(), Map.class);
result.values().forEach(System.out::println);
控制台输出:
{entityId=GvyArEFkg6JX6wI, mergePolicy={id=9245a39d-fe1a-4b33-acab-9bc5cbabf37c}}
并且如果你想将响应主体反序列化到你的DTO(我假设只有ONE根级别属性),你可以修改DTO喜欢:
public class AdobeResponseDto {
private AdobeResponseFinal adobeResponseFinal;
@JsonAnySetter
public void setAdobeResponseFinal(String name, AdobeResponseFinal value) {
adobeResponseFinal = value;
}
@JsonAnyGetter
public AdobeResponseFinal getAdobeResponseFinal() {
return adobeResponseFinal;
}
}
那么你可以得到类似如下的结果:
ResponseEntity<String> finalResponse = aepClient.exchange(uri, HttpMethod.GET, entity, String.class);
AdobeResponseDto adobeResponseDto = objectMapper.readValue(finalResponse.getBody(), AdobeResponseDto.class);
System.out.println(adobeResponseDto.getAdobeResponseFinal().toString());
控制台输出:
AdobeResponseFinal{entityId='GvyArEFkg6JX6wI', mergePolicy=MergePolicy{id='9245a39d-fe1a-4b33-acab-9bc5cbabf37c'}}