java - jackson JsonDeserializer stackoverflow

标签 java jackson

我正在尝试从 Java 中的 json 字符串中提取属性,并且我正在编写一个 JsonDeseriizer 来执行此操作。
我的尝试如下所示:

public class testJacksonSimple {
    @JsonDeserialize(using = ItemDeserializerJson.class)
    public static class Item {
        public int id;
        public String itemName;

        public Item(){};
        public Item(int id, String itemName) {
            this.id = id;
            this.itemName = itemName;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getId() {
            return id;
        }
    }

    public static class ItemDeserializerJson extends JsonDeserializer<Item> {

        ObjectReader reader = new ObjectMapper().reader();

        @Override
        public Item deserialize(JsonParser jp, DeserializationContext context) throws IOException {
            if(jp.currentToken() != JsonToken.VALUE_NULL) {
                return reader.readValue(jp, Item.class);
            } else {
                return null;
            }
        }
    }
}

这是我的测试用例:

public class test {
    public static void main(String[] args){
        ObjectMapper mapper = new ObjectMapper();
        String json = "{\n" +
                "    \"id\": 1,\n" +
                "    \"itemName\": \"theItem\"\n" +
                "}";
        System.out.println(json);
        testJacksonSimple.Item itemWithOwner = null;
        try {
            itemWithOwner = new ObjectMapper().readValue(json, testJacksonSimple.Item.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(itemWithOwner.id);
        System.out.println(itemWithOwner.itemName);
    }
}

我收到错误:

Exception in thread "main" java.lang.StackOverflowError
    at java.lang.reflect.Method.getParameterTypes(Method.java:264)
    at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:59)
    at com.sun.proxy.$Proxy2.annotationType(Unknown Source)
    at com.fasterxml.jackson.databind.introspect.AnnotationMap._add(AnnotationMap.java:135)
    at com.fasterxml.jackson.databind.introspect.AnnotationMap.addIfNotPresent(AnnotationMap.java:101)
    at com.fasterxml.jackson.databind.introspect.AnnotatedClass._addAnnotationsIfNotPresent(AnnotatedClass.java:1061)
    at com.fasterxml.jackson.databind.introspect.AnnotatedClass._resolveClassAnnotations(AnnotatedClass.java:399)
    at com.fasterxml.jackson.databind.introspect.AnnotatedClass._classAnnotations(AnnotatedClass.java:376)
    at com.fasterxml.jackson.databind.introspect.AnnotatedClass.getAnnotation(AnnotatedClass.java:248)
    at com.fasterxml.jackson.databind.AnnotationIntrospector._findAnnotation(AnnotationIntrospector.java:1436)
    at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector.findAutoDetectVisibility(JacksonAnnotationIntrospector.java:349)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.<init>(POJOPropertiesCollector.java:129)

只是不明白为什么我收到 stackoverflow 错误。我可以在不使用自定义 JSONDeserializer 的情况下获得正确的结果,但我想测试它。如有任何帮助,我们将不胜感激。

最佳答案

您已通过调用对象映射器并请求它从自定义反序列化器内部反序列化您的 json 来创建无限循环。对象映射器正在调用您的自定义反序列化器,然后您的自定义反序列化器正在调用对象映射器。因此出现了 stackoverflow。

以下内容对我有用:

    public static class ItemDeserializerJson extends JsonDeserializer<Item> {

    @Override
    public Item deserialize(JsonParser jp, DeserializationContext context) throws IOException {

        JsonNode node = jp.getCodec().readTree(jp);
        int id = (Integer) (node.get("id")).numberValue();
        String itemName = node.get("itemName").asText();

        return new Item(id, itemName);
    }
}

关于java - jackson JsonDeserializer stackoverflow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51615047/

相关文章:

java - Eclipse 系统.属性 Windows 7

java - 反序列化序列化对象时出现 ClassNotFound 异常

scala - 如何将 json4s JValue 转换为 Jackson JsonNode?

java - @JSonIgnore 注释的等效代码设置是什么?

java - 是否可以使用lombok向静态工厂方法添加注释

java - 如果日期不包含时区,则从 FormDataBodyPart/Jackson 输入 json 时抛出异常

java - MigLayout,为什么这个单元格使用了额外的空间?

java - 添加开关和 jar 文件以导出 JAVA_OPTS

java - 使用 Jackson ObjectMapper 反序列化为 Pojo<T>

java - Android: launchMode=SingleTask 问题