在解析从我们的一个RESTful Web服务接收到的JSON字符串时,我收到此错误“线程“ main”中的异常com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“人”(类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 objectObjectMapper 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 List<Person> person;public List<Person> getPerson() {return person;}public void setPerson(List<Person> 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 List<Person> person;public List<Person> getPerson() {return person;}public void setPerson(List<Person> 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;}@Overridepublic 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命令进行编译:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.2.3</version>
</dependency>
此依赖项需要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