繁体   English   中英

Jackson 与 JSON:无法识别的字段,未标记为可忽略

[英]Jackson with JSON: Unrecognized field, not marked as ignorable

我需要将某个 JSON 字符串转换为 Java object。 我正在使用 Jackson 进行 JSON 处理。 我无法控制输入 JSON(我从 web 服务读取)。 这是我的输入 JSON:

{"wrapper":[{"id":"13","name":"Fred"}]}

这是一个简化的用例:

private void tryReading() {
    String jsonStr = "{\"wrapper\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
    ObjectMapper mapper = new ObjectMapper();  
    Wrapper wrapper = null;
    try {
        wrapper = mapper.readValue(jsonStr , Wrapper.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("wrapper = " + wrapper);
}

我的实体 class 是:

public Class Student { 
    private String name;
    private String id;
    //getters & setters for name & id here
}

我的 Wrapper class 基本上是一个容器 object 来获取我的学生名单:

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

我不断收到此错误,“包装器”返回null 我不确定缺少什么。 有人可以帮忙吗?

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
    Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable
 at [Source: java.io.StringReader@1198891; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

您可以使用 Jackson 的类级注释:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
class { ... }

它将忽略您尚未在 POJO 中定义的每个属性。 当您只是在 JSON 中查找几个属性并且不想编写整个映射时非常有用。 杰克逊网站上的更多信息。 如果你想忽略任何未声明的属性,你应该写:

@JsonIgnoreProperties(ignoreUnknown = true)

你可以使用

ObjectMapper objectMapper = getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

它将忽略所有未声明的属性。

第一个答案几乎是正确的,但需要的是更改 getter 方法,而不是字段——字段是私有的(并且不会自动检测到); 此外,如果两者都可见,则 getter 优先于字段。(也有一些方法可以使私有字段可见,但如果您想拥有 getter,则没有多大意义)

所以 getter 应该被命名为getWrapper() ,或者注释为:

@JsonProperty("wrapper")

如果您更喜欢 getter 方法名称。

使用 Jackson 2.6.0,这对我有用:

private static final ObjectMapper objectMapper = 
    new ObjectMapper()
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

并设置:

@JsonIgnoreProperties(ignoreUnknown = true)

它可以通过两种方式实现:

  1. 标记 POJO 以忽略未知属性

    @JsonIgnoreProperties(ignoreUnknown = true)
  2. 如下配置序列化/反序列化 POJO/json 的 ObjectMapper:

     ObjectMapper mapper =new ObjectMapper(); // for Jackson version 1.X mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); // for Jackson version 2.X mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

这对我来说非常有效

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(
    DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

@JsonIgnoreProperties(ignoreUnknown = true)注释没有。

添加 setter 和 getter 解决了问题,我觉得实际问题是如何解决它而不是如何抑制/忽略错误。 我收到错误“无法识别的字段.. 未标记为可忽略..

尽管我在类的顶部使用了以下注释,但它无法解析 json 对象并给我输入

@JsonIgnoreProperties(ignoreUnknown = true)

然后我意识到我没有添加 setter 和 getter,在将 setter 和 getter 添加到“Wrapper”和“Student”之后,它就像一个魅力。

这比 All 效果更好,请参阅此属性。

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    projectVO = objectMapper.readValue(yourjsonstring, Test.class);

如果您使用的是 Jackson 2.0

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

根据文档,您可以忽略所选字段或所有未知字段:

 // to prevent specified fields from being serialized or deserialized
 // (i.e. not include in JSON output; or being set even if they were included)
 @JsonIgnoreProperties({ "internalId", "secretKey" })

 // To ignore any unknown properties in JSON input without exception:
 @JsonIgnoreProperties(ignoreUnknown=true)

它使用以下代码对我有用:

ObjectMapper mapper =new ObjectMapper();    
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

我已经尝试了以下方法,它适用于使用 Jackson 读取此类 JSON 格式。 使用已经建议的解决方案:使用@JsonProperty("wrapper")注释 getter

你的包装类

public Class Wrapper{ 
  private List<Student> students;
  //getters & setters here 
} 

我对包装类的建议

public Class Wrapper{ 

  private StudentHelper students; 

  //getters & setters here 
  // Annotate getter
  @JsonProperty("wrapper")
  StudentHelper getStudents() {
    return students;
  }  
} 


public class StudentHelper {

  @JsonProperty("Student")
  public List<Student> students; 

  //CTOR, getters and setters
  //NOTE: If students is private annotate getter with the annotation @JsonProperty("Student")
}

但是,这将为您提供格式的输出:

{"wrapper":{"student":[{"id":13,"name":Fred}]}}

另请参阅https://github.com/FasterXML/jackson-annotations了解更多信息

希望这有帮助

Jackson 抱怨是因为它在您的类 Wrapper 中找不到一个名为“wrapper”的字段。 这样做是因为您的 JSON 对象有一个名为“包装器”的属性。

我认为解决方法是将 Wrapper 类的字段重命名为“wrapper”而不是“students”。

此解决方案在读取 json 流时是通用的,并且只需要获取一些字段,而域类中未正确映射的字段可以忽略:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)

一个详细的解决方案是使用诸如 jsonschema2pojo 之类的工具从 json 响应的架构中自动生成所需的域类,例如 Student。 您可以通过任何在线 json 到模式转换器来完成后者。

由于 json 属性和 java 属性的名称不匹配,因此将现场学生注释如下

public Class Wrapper {
    @JsonProperty("wrapper")
    private List<Student> students;
    //getters & setters here
}

正如没有人提到的那样,我以为我会......

问题是您在 JSON 中的财产被称为“包装器”,而您在 Wrapper.class 中的财产被称为“学生”。

所以要么...

  1. 更正类或 JSON 中的属性名称。
  2. 根据 StaxMan 的评论注释您的属性变量。
  3. 注释二传手(如果你有)

对我有用的是将财产公之于众。 它为我解决了这个问题。

要么改变

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

public Class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}

- - 或者 - -

将您的 JSON 字符串更改为

{"students":[{"id":"13","name":"Fred"}]}

将您的类字段设置为public而非private

public Class Student { 
    public String name;
    public String id;
    //getters & setters for name & id here
}

就我而言,唯一的线路

@JsonIgnoreProperties(ignoreUnknown = true)

也没有用。

只需添加

@JsonInclude(Include.NON_EMPTY)

杰克逊 2.4.0

您的输入

{"wrapper":[{"id":"13","name":"Fred"}]}

表示它是一个对象,有一个名为“wrapper”的字段,它是一个学生的集合。 所以我的建议是,

Wrapper = mapper.readValue(jsonStr , Wrapper.class);

其中Wrapper定义为

class Wrapper {
    List<Student> wrapper;
}

新的 Firebase Android 引入了一些巨大的变化; 在文档副本下方:

[ https://firebase.google.com/support/guides/firebase-android]

更新您的 Java 模型对象

与 2.x SDK 一样,Firebase 数据库会自动将您传递给DatabaseReference.setValue() Java 对象转换为 JSON,并且可以使用DataSnapshot.getValue()将 JSON 读入 Java 对象。

在新的 SDK 中,当使用DataSnapshot.getValue()将 JSON 读入 Java 对象时,现在默认忽略 JSON 中的未知属性,因此您不再需要@JsonIgnoreExtraProperties(ignoreUnknown=true)

为了在将 Java 对象写入 JSON 时排除字段/getter,注释现在称为@Exclude而不是@JsonIgnore

BEFORE

@JsonIgnoreExtraProperties(ignoreUnknown=true)
public class ChatMessage {
   public String name;
   public String message;
   @JsonIgnore
   public String ignoreThisField;
}

dataSnapshot.getValue(ChatMessage.class)

AFTER

public class ChatMessage {
   public String name;
   public String message;
   @Exclude
   public String ignoreThisField;
}

dataSnapshot.getValue(ChatMessage.class)

如果您的 JSON 中有一个不在您的 Java 类中的额外属性,您将在日志文件中看到此警告:

W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage

您可以通过在类上添加@IgnoreExtraProperties注释来消除此警告。 如果您希望 Firebase 数据库像在 2.x SDK 中那样运行并在存在未知属性时抛出异常,您可以在类上添加@ThrowOnExtraProperties注释。

另一种可能性是 application.properties spring.jackson.deserialization.fail-on-unknown-properties=false中的此spring.jackson.deserialization.fail-on-unknown-properties=false ,它不需要在您的应用程序中更改任何其他代码。 当您认为合约稳定时,您可以删除此属性或将其标记为真。

如果由于某种原因您无法将 @JsonIgnoreProperties 注释添加到您的类中,并且您位于 Web 服务器/容器(例如 Jetty)中。 您可以在自定义提供程序中创建和自定义 ObjectMapper

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

@Provider
public class CustomObjectMapperProvider implements ContextResolver<ObjectMapper> {

    private ObjectMapper objectMapper;

    @Override
    public ObjectMapper getContext(final Class<?> cls) {
        return getObjectMapper();
    }

    private synchronized ObjectMapper getObjectMapper() {
        if(objectMapper == null) {
            objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }
        return objectMapper;
    }
}

这个问题已经有很多答案了。 我正在添加现有答案。

如果您想将@JsonIgnoreProperties应用于应用@JsonIgnoreProperties中的所有类,那么最好的方法是覆盖 Spring Boot 默认的 jackson 对象。

在您的应用程序配置文件中定义一个 bean 来创建这样的 jackson 对象映射器。

@Bean
    public ObjectMapper getObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper;
    }

现在,您不需要标记每个类,它会忽略所有未知属性。

谢谢。

这对我来说非常有效

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

我通过简单地更改我的 POJO 类的 setter 和 getter 方法的签名来解决这个问题。 我所要做的就是更改getObject方法以匹配映射器正在寻找的内容。 在我的情况下,我最初有一个getImageUrl ,但 JSON 数据有image_url ,这会导致映射器关闭。 我将我的 setter 和 getter 都更改为getImage_url 和 setImage_url

希望这会有所帮助。

这可能与 OP 遇到的问题不同,但如果有人遇到与我相同的错误,那么这将帮助他们解决问题。 当我使用来自不同依赖项的 ObjectMapper 作为 JsonProperty 注释时,我遇到了与 OP 相同的错误。

这有效:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;

不起作用:

import org.codehaus.jackson.map.ObjectMapper; //org.codehaus.jackson:jackson-mapper-asl:1.8.8
import com.fasterxml.jackson.annotation.JsonProperty; //com.fasterxml.jackson.core:jackson-databind:2.2.3

不知何故,在 45 个帖子和 10 年后,没有人为我的案例发布正确的答案。

@Data //Lombok
public class MyClass {
    private int foo;
    private int bar;

    @JsonIgnore
    public int getFoobar() {
      return foo + bar;
    }
}

就我而言,我们有一个名为getFoobar()的方法,但没有foobar属性(因为它是从其他属性计算而来的)。 @JsonIgnoreProperties上的@JsonIgnoreProperties不起作用。

解决办法是用@JsonIgnore注解该方法

POJO 应定义为

响应类

public class Response {
    private List<Wrapper> wrappers;
    // getter and setter
}

包装类

public class Wrapper {
    private String id;
    private String name;
    // getters and setters
}

和映射器读取值

Response response = mapper.readValue(jsonStr , Response.class);

我需要将某个JSON字符串转换为Java对象。 我正在使用Jackson进行JSON处理。 我无法控制输入的JSON(我从Web服务读取)。 这是我输入的JSON:

{"wrapper":[{"id":"13","name":"Fred"}]}

这是一个简化的用例:

private void tryReading() {
    String jsonStr = "{\"wrapper\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
    ObjectMapper mapper = new ObjectMapper();  
    Wrapper wrapper = null;
    try {
        wrapper = mapper.readValue(jsonStr , Wrapper.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("wrapper = " + wrapper);
}

我的实体类是:

public Class Student { 
    private String name;
    private String id;
    //getters & setters for name & id here
}

我的包装程序类基本上是一个容器对象,用于获取我的学生列表:

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

我不断收到此错误,“包装器”返回null 我不确定丢失了什么。 有人可以帮忙吗?

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
    Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable
 at [Source: java.io.StringReader@1198891; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

我需要将某个JSON字符串转换为Java对象。 我正在使用Jackson进行JSON处理。 我无法控制输入的JSON(我从Web服务读取)。 这是我输入的JSON:

{"wrapper":[{"id":"13","name":"Fred"}]}

这是一个简化的用例:

private void tryReading() {
    String jsonStr = "{\"wrapper\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
    ObjectMapper mapper = new ObjectMapper();  
    Wrapper wrapper = null;
    try {
        wrapper = mapper.readValue(jsonStr , Wrapper.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("wrapper = " + wrapper);
}

我的实体类是:

public Class Student { 
    private String name;
    private String id;
    //getters & setters for name & id here
}

我的包装程序类基本上是一个容器对象,用于获取我的学生列表:

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

我不断收到此错误,“包装器”返回null 我不确定丢失了什么。 有人可以帮忙吗?

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
    Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable
 at [Source: java.io.StringReader@1198891; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

我需要将某个JSON字符串转换为Java对象。 我正在使用Jackson进行JSON处理。 我无法控制输入的JSON(我从Web服务读取)。 这是我输入的JSON:

{"wrapper":[{"id":"13","name":"Fred"}]}

这是一个简化的用例:

private void tryReading() {
    String jsonStr = "{\"wrapper\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
    ObjectMapper mapper = new ObjectMapper();  
    Wrapper wrapper = null;
    try {
        wrapper = mapper.readValue(jsonStr , Wrapper.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("wrapper = " + wrapper);
}

我的实体类是:

public Class Student { 
    private String name;
    private String id;
    //getters & setters for name & id here
}

我的包装程序类基本上是一个容器对象,用于获取我的学生列表:

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

我不断收到此错误,“包装器”返回null 我不确定丢失了什么。 有人可以帮忙吗?

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
    Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable
 at [Source: java.io.StringReader@1198891; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

导入 com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties

当我们生成 getter 和 setter 时,特别是以 'is' 关键字开头的,IDE 通常会删除 'is'。 例如

private boolean isActive;

public void setActive(boolean active) {
   isActive = active;
}

public isActive(){
   return isActive;
}

就我而言,我只是更改了 getter 和 setter。

private boolean isActive;

public void setIsActive(boolean active) {
   isActive = active;
}

public getIsActive(){
   return isActive;
}

它能够识别该领域。

就我而言,这很简单:REST服务JSON对象已更新(添加了属性),但REST客户端JSON对象未更新。 一旦我更新了JSON客户端对象,“无法识别的字段...”异常就消失了。

在我的情况下,我必须添加公共 getter 和 setter 以将字段设为私有。

ObjectMapper mapper = new ObjectMapper();
Application application = mapper.readValue(input, Application.class);

我使用 jackson-databind 2.10.0.pr3 。

以防万一其他人像我一样使用force-rest-api ,这是我如何使用这个讨论来解决它(Kotlin):

var result = forceApi.getSObject("Account", "idhere")
result.jsonMapper.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,  false)
val account: Account = result.`as`(Account::class.java)

看起来 force-rest-api 正在使用杰克逊的旧版本。

您只需将List的字段从“ students”更改为“ wrapper”即可,只需json文件,然后映射器将对其进行查找。

您的 json 字符串未与映射类内联。 更改输入字符串

String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";

或者更改您的映射类

public class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}

在我的情况下,错误是由于以下原因造成的

  • 最初它工作正常,然后我重命名了一个变量,在代码中进行了更改,它给了我这个错误。

  • 然后我也应用了杰克逊无知的财产,但它没有用。

  • 最后根据我的变量名称重新定义我的 getter 和 setter 方法后,此错误已解决

所以一定要重新定义 getter 和 setter。

将 Wrapper 类更改为

public Class Wrapper {

          @JsonProperty("wrapper")  // add this line
          private List<Student> students;
}

这样做是将students字段识别为 json 对象的wrapper键。

此外,我个人更喜欢使用Lombok Annotations for Getter 和 Setter 作为

@Getter
@Setter
public Class Wrapper {

          @JsonProperty("wrapper")  // add this line
          private List<Student> students;
}

由于我没有使用 Lombok 和@JsonProperty一起测试上述代码,我建议您将以下代码添加到 Wrapper 类以及覆盖 Lombok 的默认 getter 和 setter。

public List<Student> getWrapper(){
     return students;
}

public void setWrapper(List<Student> students){
     this.students = students;
}

还要检查这个以使用 Jackson 反序列化列表。

没有 setter/getter 的最短解决方案是将@JsonProperty添加到类字段:

public class Wrapper {
    @JsonProperty
    private List<Student> wrapper;
}

public class Student {
    @JsonProperty
    private String name;
    @JsonProperty
    private String id;
}

此外,您在 json 中将学生列表称为“wrapper”,因此 Jackson 需要一个带有名为“wrapper”的字段的类。

根据本文档,您可以使用 Jackson2ObjectMapperBuilder 来构建您的 ObjectMapper:

@Autowired
Jackson2ObjectMapperBuilder objectBuilder;

ObjectMapper mapper = objectBuilder.build();
String json = "{\"id\": 1001}";

默认情况下,Jackson2ObjectMapperBuilder 禁用错误 unrecognizedpropertyexception。

json字段:

 "blog_host_url": "some.site.com"

Kotlin 领域

var blogHostUrl: String = "https://google.com"

在我的情况下,我只需要在我的数据类中使用@JsonProperty注释。

例子:

data class DataBlogModel(
       @JsonProperty("blog_host_url") var blogHostUrl: String = "https://google.com"
    )

这是文章:https://www.baeldung.com/jackson-name-of-property

ObjectMapper objectMapper = new ObjectMapper()
.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);

当我的 JSON 有效负载包含 API 无法识别的属性时,我遇到过这种情况。 解决方案是重命名/删除有问题的属性。

我遇到了类似的问题,唯一的区别是我使用的是 YAML 文件而不是 JSON 文件。 所以我在创建 ObjectMapper 时使用了 YamlFactory()。 此外,我的 Java POJO 的属性是私有的。 但是,所有这些答案中提到的解决方案都没有帮助。 我的意思是,它停止抛出错误并开始返回 Java 对象,但java 对象的属性将为空。

我刚刚做了以下事情: -

objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

并且不需要: -

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

现在,我可以将 Yaml 文件中的数据反序列化为 Java 对象。 现在所有属性都不为空。 该解决方案也适用于 JSON 方法。

下面是我试图抑制不想解析的未知道具。 分享Kotlin代码

val myResponse = jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .readValue(serverResponse, FooResponse::class.java)

Java 11 和更新版本的简单解决方案:

var mapper = new ObjectMapper()
        .registerModule(new JavaTimeModule())
        .disable(FAIL_ON_UNKNOWN_PROPERTIES)
        .disable(WRITE_DATES_AS_TIMESTAMPS)
        .enable(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);

忽略重要的是禁用“FAIL_ON_UNKNOWN_PROPERTIES”

您需要验证您正在解析的类的所有字段,使其与原始JSONObject的相同。 它帮助了我,就我而言。

@JsonIgnoreProperties(ignoreUnknown = true)根本没有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM