847

我需要将某个 JSON 字符串转换为 Java 对象。我正在使用杰克逊进行 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
}

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

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)
4

45 回答 45

1204

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

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
class { ... }

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

@JsonIgnoreProperties(ignoreUnknown = true)
于 2011-09-25T14:13:38.887 回答
629

您可以使用

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

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

于 2012-10-04T15:27:48.323 回答
143

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

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

@JsonProperty("wrapper")

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

于 2010-12-21T19:01:38.627 回答
109

使用杰克逊 2.6.0,这对我有用:

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

并设置:

@JsonIgnoreProperties(ignoreUnknown = true)
于 2015-08-11T03:59:26.417 回答
68

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

  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) 
    
于 2017-02-03T17:01:19.527 回答
50

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

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

@JsonIgnoreProperties(ignoreUnknown = true)

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

于 2019-12-12T15:15:26.440 回答
47

这对我来说非常有用

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

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

于 2013-08-13T08:19:19.863 回答
44

这比 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);
于 2013-12-17T11:09:23.760 回答
33

如果您使用的是 Jackson 2.0

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
于 2014-01-07T19:07:12.813 回答
24

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

 // 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)
于 2016-02-01T17:03:48.340 回答
19

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

ObjectMapper mapper =new ObjectMapper();    
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
于 2015-12-01T23:32:15.470 回答
17

我已经尝试了下面的方法,它适用于杰克逊的这种 JSON 格式阅读。使用已经建议的解决方案:annotating getter with@JsonProperty("wrapper")

你的包装类

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

于 2012-06-13T09:06:52.540 回答
16

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

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

于 2010-12-20T04:10:43.137 回答
14

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

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

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

于 2013-06-07T09:13:37.653 回答
12

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

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

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

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

于 2021-05-20T14:45:42.920 回答
11

由于 json 属性和 java 属性的名称不匹配,请如下注释字段学生

public Class Wrapper {
    @JsonProperty("wrapper")
    private List<Student> students;
    //getters & setters here
}
于 2016-11-16T17:23:49.460 回答
9

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

所以要么...

  1. 更正类或 JSON 中的属性名称。
  2. 根据 StaxMan 的评论注释您的属性变量。
  3. 注释二传手(如果你有的话)
于 2012-04-16T15:43:44.243 回答
7

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

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

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

在我的例子中,我们有一个名为 的方法getFoobar(),但没有foobar属性(因为它是从其他属性计算出来的)。 @JsonIgnoreProperties对类不起作用。

解决方案是用注释方法@JsonIgnore

于 2020-12-16T20:14:47.320 回答
6

对我有用的是让财产公开。

于 2014-05-25T10:14:01.933 回答
6

要么改变

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"}]}
于 2014-08-27T06:25:17.610 回答
5

就我而言,唯一的线路

@JsonIgnoreProperties(ignoreUnknown = true)

也没有用。

只需添加

@JsonInclude(Include.NON_EMPTY)

杰克逊 2.4.0

于 2014-09-15T11:53:08.737 回答
5

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

于 2015-05-19T03:52:49.893 回答
5

将您的类字段设置为公开,而不是私有

public Class Student { 
    public String name;
    public String id;
    //getters & setters for name & id here
}
于 2018-06-13T15:25:17.620 回答
5

如果由于某种原因您无法将 @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;
    }
}
于 2021-02-25T15:12:38.347 回答
5

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

于 2019-01-31T10:49:33.167 回答
5

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

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

更新您的 Java 模型对象

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

在新的 SDK 中,当使用 将 JSON 读入 Java 对象时DataSnapshot.getValue(),默认情况下会忽略 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在您的类上添加注释。

于 2016-07-08T09:37:35.943 回答
5

您的意见

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

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

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

其中Wrapper定义为

class Wrapper {
    List<Student> wrapper;
}
于 2016-04-12T12:31:19.853 回答
4

这对我来说非常有用

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
于 2015-03-04T22:04:38.463 回答
4

这可能与 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
于 2019-06-10T22:04:31.127 回答
3

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);
于 2014-04-01T06:09:47.637 回答
3

FAIL_ON_UNKNOWN_PROPERTIES选项默认为 true:

FAIL_ON_UNKNOWN_PROPERTIES (default: true)
Used to control whether encountering of unknown properties (one for which there is no setter; and there is no fallback "any setter" method defined using @JsonAnySetter annotation) should result in a JsonMappingException (when enabled), or just quietly ignored (when disabled)
于 2019-11-06T12:45:35.967 回答
3

这可能是一个很晚的响应,但是只需将 POJO 更改为此应该可以解决问题中提供的 json 字符串(因为输入字符串不在您的控制范围内):

public class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}
于 2017-08-23T22:03:05.683 回答
2

谷歌把我带到了这里,我很惊讶地看到了答案......所有人都建议绕过错误(在开发后期总是咬回 4 折)而不是解决它,直到这位绅士恢复对 SO 的信心!

objectMapper.readValue(responseBody, TargetClass.class)

用于将 json String 转换为类对象,缺少的是TargetClass应该有 public getter / setters。OP的问题片段中也缺少相同的内容!:)

通过龙目岛,您的课程如下应该可以工作!

@Data
@Builder
public class TargetClass {
    private String a;
}
于 2018-02-13T11:02:22.237 回答
2

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

@JsonIgnoreProperties

于 2019-08-29T01:38:57.480 回答
2

当我们生成 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;
}

它能够识别该领域。

于 2019-10-02T17:19:50.743 回答
1

在我的情况下,我必须添加公共 getter 和 setter 以使字段保持私有。

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

我使用 jackson-databind 2.10.0.pr3 。

于 2019-09-27T15:06:16.130 回答
1

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

于 2016-06-13T10:20:49.783 回答
1

以防万一其他人像我一样使用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 使用的是杰克逊的旧版本。

于 2021-06-17T19:17:25.797 回答
0

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

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

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

此外,您在 json 中将学生列表称为“包装器”,因此杰克逊期望一个具有名为“包装器”的字段的类。

于 2020-12-03T14:00:08.357 回答
0

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

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

或更改您的映射类

public class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}
于 2016-06-19T20:21:37.830 回答
0

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

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

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

  • 最后根据我的变量名称重新定义我的getter和setter方法后,这个错误得到了解决

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

于 2018-02-20T06:06:01.993 回答
0

将 Wrapper 类更改为

public Class Wrapper {

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

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

此外,我个人更喜欢将Lombok Annotations用于 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 反序列化列表。

于 2018-04-07T09:10:22.727 回答
0

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

@Autowired
Jackson2ObjectMapperBuilder objectBuilder;

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

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

于 2021-11-13T17:53:58.050 回答
0

您只需将 json 文件的 List 字段从“students”更改为“wrapper”,映射器就会查找它。

于 2015-12-10T17:08:49.233 回答
-2

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

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

于 2017-02-21T13:35:20.617 回答