使用Jackson忽略JSON对象上的新字段

743

我正在使用Jackson JSON库将一些JSON对象转换为POJO类,在Android应用程序上。问题是,JSON对象可能会在应用程序发布时改变并添加新字段,但即使添加了一个简单的字符串字段(可以安全忽略)也会导致应用程序崩溃。

有没有办法告诉Jackson忽略新添加的字段?(例如, POJO对象中不存在的字段) 一个全局的忽略选项会很好。

12个回答

1029

Jackson提供了一个可以在类级别上使用的注释(JsonIgnoreProperties)。

在你的类顶部添加以下内容(而不是个别方法):

@JsonIgnoreProperties(ignoreUnknown = true)
public class Foo {
    ...
}

根据您使用的jackson版本,您需要使用不同的导入方式,当前版本为:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

在旧版本中,它是这样的:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

3
尝试在Jackson 2.x库上使其工作。该包现在更改为 com.fasterxml.jackson.annotation.JsonIgnoreProperties,但对我来说它不起作用。你有什么想法吗? - Niks
1
在我的gradle文件中使用这个库:'com.fasterxml.jackson.core:jackson-annotations:2.3.2' + com.fasterxml.jackson.annotation.JsonIgnoreProperties,与jackson核心库一起使用对我很有效。 - Whitney Imura
8
如何使用ObjectMapper来实现这个? - blackuprise
1
使用@NikhilPatil建议的com.fasterxml.jackson.annotation.JsonIgnoreProperties导入,它可以正常工作。 - Roger
17
有没有办法在ObjectMapper级别上做到这一点?我无法编辑正在反序列化的类。很多人使用它并且他们在反序列化期间需要那些字段,但我不需要。这些字段是已知属性。 - Ava
显示剩余4条评论

563

除了已经提到的两种机制外,还有一种全局特性可用于抑制由未知(未映射)属性引起的所有失败:

// jackson 1.9 and before
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// or jackson 2.0
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

这是在缺少注释时使用的默认值,并且可以作为方便的后备选项。


这种方法对我来说是必需的,因为目标 POJO 具有我们不拥有的类型成员,并且该成员具有自己的自定义反序列化(它将使用“隐藏”属性,如“__type”来执行某些类型的魔术,例如多态类型的实例化)。谢谢! - scorpiodawg
1
这是为客户手动解组的! - Marcello DeSales
12
请注意,Spring >= 4.1.1 会自动将此设置为 false,且不会给出提示。具体信息请参阅 https://jira.spring.io/browse/SPR-11891。 - bigstones
4
为什么这个配置对我没有影响?Jackson 版本是 2.6.4 或 2.7.0。 - zhaozhi
2
@zhaozhi 这些设置已经存在很长时间了,所以尽管你应该升级到分支的最新补丁(2.6.7、2.7.9),但这可能不是原因。最常见的原因是你正在使用的框架没有使用你配置的 ObjectMapper - StaxMan
2
我不同意,如果字段更改名称,这将会悄悄失败,除非我们逐个检查每个字段,否则我们不知道发生了什么。在我的情况下,甚至忽略了DTO缺少任何字段定义时的失败,这非常危险。因此,它将忽略任何类型的失败;请谨慎使用。 - WesternGun

159

使用Jackson 2获取最新的和完整的答案


使用注解

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class MyMappingClass {

}

请参阅Jackson在线文档的JsonIgnoreProperties

使用配置

比注释更少侵入性。

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

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

ObjectReader objectReader = objectMapper.reader(MyMappingClass.class);
MyMappingClass myMappingClass = objectReader.readValue(json);

请参阅Jackson在线文档中的FAIL_ON_UNKNOWN_PROPERTIES


8
这个答案非常有用,特别是在无法编辑MappingClass以添加注释的情况下。 - Neuro
2
您还可以直接使用 reader.without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) 配置 ObjectReader。 - fono
点赞。但添加“使用di.xml”链接。(依赖注入 .xm):https://dev59.com/smYq5IYBdhLWcg3woB0W#14343479 - granadaCoder

94

这可以通过以下两种方式实现:

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

@JsonIgnoreProperties(ignoreUnknown = true)
  • 配置ObjectMapper来序列化/反序列化POJO/json,如下所示:

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

    34

    @JsonIgnoreProperties(ignoreUnknown = true) 对我非常有效。我有一个运行在JDK 1.7的Tomcat上的Java应用程序。


    可以在JDK 1.8下使用Spring Boot应用程序工作(不需要此答案中步骤#2)。 - Bimde

    26

    如果使用基于JSON响应的POJO类,如果有可能JSON经常发生更改,请在POJO类级别声明:

    @JsonIgnoreProperties(ignoreUnknown = true)
    

    如果你正在进行转换,则在objectMapper中添加以下内容:

    objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    

    这样代码就不会出现错误。


    19

    从Jackson 2.4版本开始,有一些变化。现在的做法是:

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

    ..........................................................................

     ObjectMapper mapper = new ObjectMapper();
        // to prevent exception when encountering unknown property:
     mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    

    注意:基于@annotation的解决方案保持不变,因此如果您喜欢使用它,请参阅其他答案。
    有关更多信息,请参见10分钟配置教程:https://github.com/FasterXML/jackson-databind

    17

    确保将 @JsonIgnoreProperties(ignoreUnknown = true) 注解放置在要作为解析 JSON 响应结果的父级 POJO 类上,而不是在从JSON转换为Java对象的类中。


    1
    这种行为有任何特别的原因吗? - Twaha Mehmood
    @tm.sauron 在目标类上添加注释是合理的,因为您不知道源类中有哪些字段是未知的。 - Priyank

    11

    如上所述,仅当在父POJO类中指定而不是进行从JSON到Java对象的转换的类中指定时,注释才起作用。

    另一种替代方法是,在不触及父类并引起干扰的情况下,为您需要的映射器方法实现自己的映射器配置。

    此外,反序列化功能的包已被移动。 DeserializationConfig.FAIL_ON_UNKNOWN_PROPERTIES 变为 DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES。

    import org.codehaus.jackson.map.DeserializationConfig;
    ...
    objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    

    10
    < p > 如果你正在使用Spring Boot,你可以通过使用 Jackson2ObjectMapperBuilder 来配置Jackson的默认行为。

    例如:


    @Bean
    public Jackson2ObjectMapperBuilder configureObjectMapper() {
        Jackson2ObjectMapperBuilder oMapper = new Jackson2ObjectMapperBuilder();
        oMapper.failOnUnknownProperties(false);
        return oMapper;
    }
    

    然后你可以在需要的任何地方自动装配ObjectMapper (默认情况下,这个对象映射器也将用于HTTP内容转换)。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接