杰克逊JsonDeserializer stackoverflow

时间:2018-07-31 13:54:15

标签: 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的情况下获得正确的结果,但是我想对其进行测试。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:3)

您已经通过调用objectmapper并请求其从自定义反序列化器内部反序列化json来创建无限循环。对象映射器将调用您的自定义解串器,然后您的自定义解串器将调用对象映射器。因此,stackoverflow。

以下对我有用:

Kotlin

答案 1 :(得分:0)

因此,基本上reader.readValue(jp, Item.class);会循环调用反序列化方法。 顺便说一下,请保持命名约定(类名应为UpperCamelCase):http://www.oracle.com/technetwork/java/javase/overview/codeconventions-135099.html