我正在尝试从 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/