Java Jackson JSON映射到具有树遍历的对象

Java Jackson JSON映射到具有树遍历的对象,java,json,mapping,jackson,resttemplate,Java,Json,Mapping,Jackson,Resttemplate,我有以下JSON,我想将其映射到一个对象 { "response": { "original": { "status": { "code": "SUCCESS" }, "organisationNode": [ { "organisationId": {

我有以下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;
  }
}
ResponseEntity<Structure> response = restTemplate.postForEntity(endpoint, requestObject, Structure.class);
我使用restTemplate调用JSON服务(它为我提供上面的JSON响应),如下所示:

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;
  }
}
ResponseEntity<Structure> response = restTemplate.postForEntity(endpoint, requestObject, Structure.class);
ResponseEntity response=restemplate.postForEntity(端点、请求对象、结构.class);
表示,如果pom.xml中存在此依赖项,并且spring上下文中的标记
,spring MVC会自动为REST模板注册一个JSON转换器

<dependency>
   <groupId>org.codehaus.jackson</groupId>
   <artifactId>jackson-mapper-asl</artifactId>
   <version>1.9.3</version>
</dependency>

org.codehaus.jackson
杰克逊地图绘制者
1.9.3
JSON字符串和Java对象中存在一些不一致之处。
例如,
Status
也应该是带有字段代码而不是字符串的类型

没有Jackson注释将对象字段映射到树中的Json节点,但实现起来并不困难。这里有三件事需要做:

  • 使用路径值创建自定义注释
  • 创建一个自定义反序列化程序,该程序将根据注释的路径值定位节点,并将其转换为字符串
  • 注册一个,它将告诉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));
        }
    }
    

    我有这种依赖性,这不是问题所在。但是我不想创建一个类响应,它的原始字段包含一个字段状态,该字段状态包含一个字段代码。这是一种冗长的方式。我想让te JSON结构平展一点。