我有以下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 Object看起来像这样:
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;
}
}
有没有某种杰克逊注释可以看到例如:
@SomeAnnotation("response.original.status.code")
private String status;
我正在使用restTemplate调用JSON服务(它为我提供上面的JSON响应):
ResponseEntity<Structure> response = restTemplate.postForEntity(endpoint, requestObject, Structure.class);
答案 0 :(得分:1)
没有Jackson注释将对象字段映射到树中的Json节点,但实现起来并不困难。以下是需要完成的3个方面:
以下是完整的示例:
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'}
答案 1 :(得分:0)
Spring Documentation表示如果你的pom.xml中有这种依赖关系并且你的spring上下文中有标记<mvc:annotation-driven>
,那么Spring MVC会自动为你的REST模板注册一个JSON转换器
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.3</version>
</dependency>
您的JSON字符串和Java对象中存在一些不一致之处。
例如。 Status
也应该是具有字段代码而不是字符串