gpt4 book ai didi

java - Jackson JSON 通过树遍历映射到对象

转载 作者:行者123 更新时间:2023-12-01 12:49:56 24 4
gpt4 key购买 nike

我有以下 JSON,我想将其映射到一个对象。

{
"response": {
"original": {
"status": {
"code": "SUCCESS"
},
"organisationNode": [
{
"organisationId": {
"identifier": "2005286047",
"identifierType": "BECBE"
},
"organisationLevel": "Subdivision",
"organisationCode": "ENT_CBE",
"organisationParentNode": {
"organisationId": {
"identifier": "0878016185",
"identifierType": "BEEUN"
},
"organisationLevel": "Entity",
"organisationCode": "ENT_CBE"
}
}
]
}
}
}

我希望我的 Java 对象看起来像这样:

public class Structure {

private String status; //SUCCESS

private List<OrganisationNode> organisationNodes;

public class OrganisationNode {
private String organisationId; //2005286047
private String organisationLevel; //Subdivision

private List<OrganisationNode> organisationNodes;
}
}

是否有某种 Jackson 注释可供查看,例如:

@SomeAnnotation("response.original.status.code")
private String status;

我正在使用restTemplate调用JSON服务(它为我提供上面的JSON响应),如下所示:

ResponseEntity<Structure> response = restTemplate.postForEntity(endpoint, requestObject, Structure.class);

最佳答案

没有 Jackson 注释将对象字段映射到树中的 Json 节点,但实现起来并不难。以下是需要完成的 3 件事:

  1. 创建带有路径值的自定义注释。
  2. 创建一个自定义反序列化器,它将根据注释的路径值定位节点并将其转换为字符串。
  3. 注册 annotation introspector这会告诉 Jackson,用您的注释注释的字段或参数已映射到 json 属性,并且应该使用您的反序列化器。

这是完整的示例:

public class JacksonContextualSerializer {

@Retention(RetentionPolicy.RUNTIME)
public static @interface SomeAnnotation {
String value();
}

public static final String JSON = "{\n" +
" \"response\": {\n" +
" \"original\": {\n" +
" \"status\": {\n" +
" \"code\": \"SUCCESS\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";

public static class PathAwareSerializer extends JsonDeserializer<String>
implements ContextualDeserializer {
private String path;

@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property)
throws JsonMappingException {
// when the serializer implements the ContextualDeserializer, then we have
// the access to the element's annotation value
path = property.getMember().getAnnotation(SomeAnnotation.class).value();
return this;
}

@Override
public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
// read JSON as tree
JsonNode node = jp.readValueAs(JsonNode.class);
// find the last node starting from the second path element, since the first
// is covered by the property name (see the introspector)
String[] pathArray = path.split("\\.");
for (int i = 1; i < pathArray.length; i++) {
node = node.get(pathArray[i]);
}
return node.asText();
}
}

public static class Bean {
private final String status;

@JsonCreator
public Bean(@SomeAnnotation("response.original.status.code") String status) {
this.status = status;
}

@Override
public String toString() {
return "Bean{" +
"status='" + status + '\'' +
'}';
}
}

public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
// register an introspector which will inject jackson annotations to elements that are
// marked by the custom annotation.
mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
public PropertyName findNameForDeserialization(Annotated a) {
if (a.hasAnnotation(SomeAnnotation.class)) {
// if annotation is present then this is a property which name is the first
// element in the path
String path = a.getAnnotation(SomeAnnotation.class).value();
return new PropertyName(path.split("\\.")[0]);
}
return super.findNameForDeserialization(a);
}

@Override
public Class<? extends JsonDeserializer<?>> findDeserializer(Annotated a) {
// if the annotation is present, then the property is deserialized using
// the custom serializer
if (a.hasAnnotation(SomeAnnotation.class)) {
return PathAwareSerializer.class;
}
return super.findDeserializer(a);
}
});

System.out.println(mapper.readValue(JSON, Bean.class));
}
}

输出:

Bean{status='SUCCESS'}

关于java - Jackson JSON 通过树遍历映射到对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24308149/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com