杰克逊JSON解析错误-UnrecognizedPropertyException:无法识别的字段,未标记为可忽略[已解决]...

解析从我们的一个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 List person;

  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运行相同的程序时,将出现以下错误:

杰克逊JSON解析错误-UnrecognizedPropertyException:无法识别的字段,未标记为可忽略[已解决]..._第1张图片

同样, 杰克逊无法识别新的“ 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;

    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。

杰克逊JSON解析错误-UnrecognizedPropertyException:无法识别的字段,未标记为可忽略[已解决]..._第2张图片

现在,让我们看看真正的错误:

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 。

杰克逊JSON解析错误-UnrecognizedPropertyException:无法识别的字段,未标记为可忽略[已解决]..._第3张图片

这是一门免费的在线课程,旨在学习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-corejackson-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

你可能感兴趣的:(java,编程语言,python,linux,大数据)