簡體   English   中英

Jackson JSON無法使用自定義根名反序列化元素數組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM