Java Jackson JSON无法反序列化具有自定义根名称的元素数组?

Java Jackson JSON无法反序列化具有自定义根名称的元素数组?,java,arrays,json,jackson,deserialization,Java,Arrays,Json,Jackson,Deserialization,我有一个Json,看起来像这样: { "testEntities" : [ { "id" : 1, "floatNumber" : 0.006117165, "floatNumberObject" : 0.15273619, "intNumber" : -1155869325, "intNumberObject" : 431529176, "doubleNumber" : 0.41008081149220166, "doubleNumb

我有一个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
类有一个我创建的自定义注释,名为
jsonrootnamemultral
,当根元素是集合而不是单个实例时使用:

@JsonRootName("testEntity")
@JsonRootNamePlural("testEntities")
public class TestObject {
   ...
}
系统的其他位置也需要此注释

我希望它使用它的方式与使用
@JsonRootName
注释的方式相同,但数组除外。因此,它可以查找由JsonRootName指示的根元素,如果没有找到,则可以查找@jsonrootnamemultral。Jackson应该忽略JSON中的所有其他根名称

问题是,我应该覆盖或自定义什么来引入这种行为?


非常感谢您的帮助和指点,谢谢

找到了我自己问题的答案:需要在对象映射器上设置一个自定义的
JacksonAnnotationIntrospector
实例,该实例覆盖
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);
    }
@覆盖
公共属性名称findRootName(注释类ac){
//如果这是一个数组,请在
//数组的基类型(所谓的数组组件)
if(ac.getRawType().isArray()){
类arrayComponent=ac.getRawType().getComponentType();
JsonRootNamePlumal-ann=arrayComponent.getAnnotation(JsonRootNamePlumal.class);
如果(ann!=null){
返回PropertyName.construct(ann.value(),null);
}
}
//超类将查找默认的@JsonRootName注释
返回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);
    }
}
请注意readArrayFromJson()方法中的arrayClazz变量应该是数组的类(例如MyObject[].class)

     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);
            }
        }