[英]Jackson JSON not able to deserialize array of elements with custom root name?
我有一个看起来像这样的Json:
{
"testEntities" : [ {
"id" : 1,
"floatNumber" : 0.006117165,
"floatNumberObject" : 0.15273619,
"intNumber" : -1155869325,
"intNumberObject" : 431529176,
"doubleNumber" : 0.41008081149220166,
"doubleNumberObject" : 0.20771484130971707,
"shortNumber" : 9364,
"shortNumberObject" : 13977,
"booleanValue" : true,
"booleanValueObject" : true,
"byteValue" : -79,
"charValue" : "e",
"charValueObject" : "b",
"creationDate" : 86400000
}, {
"id" : 2,
"floatNumber" : 0.9874208,
"floatNumberObject" : 0.45285606,
"intNumber" : -1154715079,
"intNumberObject" : 1260042744,
"doubleNumber" : 0.9014476240300544,
"doubleNumberObject" : 0.49682259343089075,
"shortNumber" : 483,
"shortNumberObject" : 18322,
"booleanValue" : false,
"booleanValueObject" : true,
"byteValue" : -73,
"charValue" : "c",
"charValueObject" : "r",
"creationDate" : 172800000
} ]
}
当我尝试反序列化时,它失败并显示:
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Root name 'testEntities' does not match expected ('TestObject[]') for type
我已经启用了数组反序列化:
objectMapper.enable(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY);
显然, testEntities
是杰克逊一无所知的自定义名称。 我创建的TestObject
类有一个自定义注释,称为JsonRootNamePlural
,当根元素是一个集合而不是单个实例时可以使用:
@JsonRootName("testEntity")
@JsonRootNamePlural("testEntities")
public class TestObject {
...
}
系统的其他地方也需要此注释。
我希望它使用与@JsonRootName
批注相同的方式,但数组除外。 因此,它可以查找JsonRootName指示的根元素,如果找不到,则可以查找@JsonRootNamePlural。 杰克逊应忽略JSON中的所有其他根名称。
问题是, 我应该重写或自定义什么以引入此行为?
非常感谢任何帮助或指点,谢谢!
找到了我自己的问题的答案:需要在对象映射器上设置一个JacksonAnnotationIntrospector
findRootName
的自定义实例,该实例将覆盖findRootName
方法,然后检查该类是否为数组,如果是,则在数组组件类中查找自定义注释,如下所示:
@Override
public PropertyName findRootName(AnnotatedClass ac) {
// if this is an array, look for JsonRootNamePlural annotation in
// the base type for the array (the so called array component)
if (ac.getRawType().isArray()) {
Class<?> arrayComponent = ac.getRawType().getComponentType();
JsonRootNamePlural ann = arrayComponent.getAnnotation(JsonRootNamePlural.class);
if (ann != null) {
return PropertyName.construct(ann.value(), null);
}
}
// super class will look for default @JsonRootName annotation
return super.findRootName(ac);
}
希望这会帮助别人,
干杯!
非常感谢!)您真的有帮助! 我是注释创建的新手,所以我将写我的操作方式,也许创建自己的注释会很容易。 这是一个注释类:
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonRootNamePlural {
String value();
}
我的内省班级:
class ArrayRootNameAnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public PropertyName findRootName(AnnotatedClass ac) {
if (ac.getRawType().isArray()) {
Class<?> arrayComponent = ac.getRawType().getComponentType();
JsonRootNamePlural ann = arrayComponent.getAnnotation(JsonRootNamePlural.class);
if (ann != null) {
return PropertyName.construct(ann.value(), null);
}
}
return super.findRootName(ac);
}
}
和JsonUtil类:
public static Object readArrayFromJson(String responseString,Class arrayClazz) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
mapper.setAnnotationIntrospector(new ArrayRootNameAnnotationIntrospector());
mapper.findAndRegisterModules();
try {
return mapper.readValue(responseString, arrayClazz);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
请注意,readArrayFromJson()方法中的arrayClazz变量应为数组类(例如MyObject []。class)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.