解析从我们的一个RESTful Web服务接收到的JSON字符串时,我收到此错误“线程“ main”中的异常com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“ person”(类Hello $ Person),不是标记为“可忽略” 。
经过一番研究,我发现这是在Java应用程序中使用Jackson开源库解析JSON文档时的常见错误之一。 错误消息说在我们的例子中,它找不到合适的属性名称“ person”,让我们首先看一下我们要解析的JSON,用于表示JSON文档的类和错误。消息本身。
错误信息:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "person" (class Hello$Person), not marked as ignorable (4 known properties: , "id", "city", "name", "phone"])
错误消息指出,它可以在Person类中找到ID,城市,名称和电话属性,但无法找到“ person”字段。
我们的POJO类如下所示:
class Person{ private int id; private String name; private String city; private long phone; ..... }
和JSON字符串:
{ "person": [ { "id": "11", "name": "John", "city": "NewYork", "phone": 7647388372 } ] }
如果仔细看,“ person”字段指向JSON数组而不是对象,这意味着它不能直接映射到person类。
如何解决这个问题呢
以下是解决此问题并摆脱此错误的步骤:
1)配置encunger未知属性时,杰克逊的ObjectMapper不会失败
您可以通过禁用ObjectMapper的D eserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
属性来执行此操作,如下所示:
// Jackson code to convert JSON String to Java object ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); Person p = objectMapper.readValue(JSON, Person.class); System.out.println(p);
现在,错误将消失,但是输出不是您期望的,它将输出以下内容:
Person [id=0, name=null, city=null, phone=0]
您可以看到Person
类没有正确创建,即使JSON String包含其值,相关属性也为null。
原因是JSON String包含一个JSON数组 ,person字段指向一个数组,而Person
类中没有对应于该字段的字段。
为了正确地解析JSON字符串,我们需要创建一个包装器类Community
,它将具有一个属性来保留Person数组,如下所示:
static class Community { private Listperson; public List getPerson() { return person; } public void setPerson(List person) { this.person = person; } }
现在,我们将JSON字符串转换为该Community
类,并从列表中打印每个人,如下所示:
ObjectMapper objectMapper = new ObjectMapper(); //objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); Community c = objectMapper.readValue(JSON, Community.class); for (Person p : c.getPerson()) { System.out.println(p); }
这将正确打印人的详细信息,如下所示:
Person [id=11, name=John, city=NewYork, phone=7647388372]
现在,回到更普遍的情况, 在JSON上添加了一个新字段,但您的Person类中不提供新字段 ,让我们看看会发生什么。
假设我们要解析的JSON字符串如下:
{ "person": [ { "id": "11", "name": "John", "city": "NewYork", "phone": 7647388372, "facebook": "JohnTheGreat" } ] }
使用此JSON String运行相同的程序时,将出现以下错误:
同样, 杰克逊无法识别新的“ facebook”属性。 现在,我们可以通过禁用告诉Jackson在未知属性上失败的功能来忽略此属性,如下所示:
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); Community c = objectMapper.readValue(JSON, Community.class);
这将正确打印人员类别,如下所示:
Person [id=11, name=John, city=NewYork, phone=7647388372]
或者,您也可以使用@JsonIgnoreProperties
批注忽略未声明的属性。
@JsonIgnoreProperties
是Jackson中的一个类级注释,它将忽略您尚未在POJO中定义的每个属性。 当您仅在JSON中查找几个属性并且不想编写整个映射时,此功能非常有用。
该注释在类级别提供控制,即您可以告诉Jackson ,对于该类,请忽略通过执行以下操作未定义的任何属性
@JsonIgnoreProperties(ignoreUnknown = true)
因此,我们的Person类现在看起来像:
@JsonIgnoreProperties(ignoreUnknown = true) static class Person{ private int id; private String name; private String city; private long phone; ...... }
样例程序
import java.io.IOException; import java.util.List; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; /* * { "person": [ { "id": "11", "name": "John", "city": "NewYork", "phone": 7647388372 } ] } */ public class Hello { private static String JSON = "{\r\n" + " \"person\": [\r\n" + " {\r\n" + " \"id\": \"11\",\r\n" + " \"name\": \"John\",\r\n" + " \"city\": \"NewYork\",\r\n" + " \"phone\": 7647388372,\r\n" + " \"facebook\": \"JohnTheGreat\"\r\n" + " }\r\n" + " ]\r\n" + " } "; public static void main(String args[]) throws JsonParseException, JsonMappingException, IOException { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); Community c = objectMapper.readValue(JSON, Community.class); for (Person p : c.getPerson()) { System.out.println(p); } } static class Community { private Listperson; public List getPerson() { return person; } public void setPerson(List person) { this.person = person; } } static class Person { private int id; private String name; private String city; private long phone; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public long getPhone() { return phone; } public void setPhone(long phone) { this.phone = phone; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", city=" + city + ", phone=" + phone + "]"; } } }
当我运行该程序的第一个版本时,遇到以下错误:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class Hello$Person]: can not instantiate from JSON object (need to add/enable type information?) at [Source: java.io.StringReader@5e329ba8; line: 2, column: 3] at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:984) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:276) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034) at Hello.main(Hello.java:40)
发生此错误是因为我的嵌套类 Person不是静态的,这意味着由于具有任何Outer类实例而无法将其实例化。 使Person
类变为静态后,该问题得以解决。
如果您以前不熟悉此细节,建议您检查一下
Java基础知识:核心平台 ,这是Pluralsight的免费课程,旨在学习有关Java编程语言的此类详细信息。 您可以注册一个免费试用版,这使您有10天的访问时间,足以免费学习整个Java。
现在,让我们看看真正的错误:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "person" (class Hello$Person), not marked as ignorable (4 known properties: , "id", "city", "name", "phone"]) at [Source: java.io.StringReader@4fbc9499; line: 2, column: 14] (through reference chain: Person["person"]) at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79) at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:555) at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:708) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1160) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:315) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034) at Hello.main(Hello.java:40)
当您运行程序的最终版本时,将看到以下输出:
Person [id=11, name=John, city=NewYork, phone=7647388372]
这意味着我们能够在Jackson中成功解析包含未知属性的JSON 。
如何编译和运行该程序?
您可以简单地将代码复制粘贴到您喜欢的IDE(例如Eclipse)中,以编译和运行该程序。
在Eclipse中,您甚至不需要创建类文件,因为如果将代码复制粘贴到Java项目中,它将自动创建类和包。
如果Eclipse是您的主要IDE,并且您想了解更多这样的工作效率提示,建议您查看
Eclipse导览–第1部分和第2部分作者:Tod Gentille 。
这是一门免费的在线课程,旨在学习Eclipse IDE的基本和高级功能,这是每个Java开发人员都应注意的。 您可以通过注册免费试用版来访问此课程,从而使您有10天的时间访问整个Pluralsight库,这是学习编程和其他技术的最有价值的资源之一。 顺便说一句,十天就足够一起学习Java和Eclipse。
无论如何,一旦复制粘贴代码,您所需要做的就是在pom.xml中包含Maven依赖项,或者手动下载Jackson开源库所需的JAR文件 。
对于Maven用户
您可以在项目的pom.xml上添加以下Maven依赖项,然后运行mvn build或mvn install命令进行编译:
com.fasterxml.jackson.core jackson-databind 2.2.3
此依赖项需要jackson-core
和jackson-annotations
但Maven会自动为您下载该依赖项。
手动下载JAR
如果您不使用Maven或任何其他构建工具eggradle,则可以转到Maven中央库并下载以下三个JAR文件,并将它们包括在类路径中:
jackson-databind-2.2.3.jar jackson-core-2.2.3.jar jackson-annotations-2.2.3.jar
一旦成功编译了类,就可以像在Eclipse中运行任何其他Java程序一样运行它们,如此处所示,或者可以使用命令行运行JAR文件,如下所示
在这里 。
简而言之,当您尝试将JSON解析为不包含JSON中定义的所有字段的Java对象时,会出现“ com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段XXX,未标记为可忽略”的错误。 您可以通过禁用Jackson的功能来解决此错误,该功能会告诉它如果遇到未知属性时将失败,或者通过在类级别使用注释@JsonIgnoreProperties
来@JsonIgnoreProperties
。
进阶学习
- Spring MVC简介
- Eugen Paraschiv的Spring REST
- 使用Jersey的Java中的RESTFul Services
感谢您到目前为止阅读本文。 如果您喜欢我的解释,请与您的朋友和同事分享。 如果您有任何疑问或反馈,请留下笔记。
翻译自: https://www.javacodegeeks.com/2017/10/jackson-json-parsing-error-unrecognizedpropertyexception-unrecognized-field-not-marked-ignorable-solved.html