使用 Jackson 忽略 JSON 对象上的新字段 [重复]

Posted

技术标签:

【中文标题】使用 Jackson 忽略 JSON 对象上的新字段 [重复]【英文标题】:Ignoring new fields on JSON objects using Jackson [duplicate] 【发布时间】:2011-07-24 05:22:59 【问题描述】:

我正在使用 Jackson JSON 库将一些 JSON 对象转换为 android 应用程序上的 POJO 类。问题是,在发布应用程序时,JSON 对象可能会更改并添加新字段,但目前即使添加了简单的 String 字段,它也会中断,可以安全地忽略它。

有没有办法告诉杰克逊忽略新添加的字段? (例如 POJO 对象上不存在)?全局忽略会很棒。

【问题讨论】:

【参考方案1】:

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

将以下内容添加到类的顶部(添加到单个方法):

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

根据您使用的杰克逊版本,您必须在当前版本中使用不同的导入:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

在旧版本中是这样的:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

【讨论】:

试图让它在 Jackson 2.x 库上工作。这个包现在更改为com.fasterxml.jackson.annotation.JsonIgnoreProperties,它对我不起作用。有什么想法吗? 在我的 gradle 文件中使用这个库:'com.fasterxml.jackson.core:jackson-annotations:2.3.2' + com.fasterxml.jackson.annotation.JsonIgnoreProperties 适用于我的杰克逊核心库。 如何用 ObjectMapper 做到这一点? 它使用 @NikhilPatil 建议的 com.fasterxml.jackson.annotation.JsonIgnoreProperties 导入工作 有什么方法可以在 ObjectMapper 级别上做到这一点?我无法编辑我正在反序列化的类。许多人使用它,他们在反序列化期间需要这些字段,但我不需要。这些字段是已知属性。【参考方案2】:

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

// 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);

这是在没有注释的情况下使用的默认值,可以方便的回退。

【讨论】:

这是供客户手动整理的! 请注意 Spring >= 4.1.1 会自动将此设置为 false,恕不另行通知...jira.spring.io/browse/SPR-11891 为什么这个配置对我没有影响?杰克逊版本 2.6.4 或 2.7.0 @zhaozhi 这些设置已经存在很长时间了,所以虽然你真的应该升级到分支的最新补丁(2.6.7、2.7.9),但这可能不是原因。最常见的原因是您使用的框架没有使用您正在配置的ObjectMapper 我不同意,但如果字段更改名称,这将静默失败,除非我们逐个字段检查,否则我们不知道发生了什么。在我的例子中,它甚至在 DTO 缺少任何字段定义时忽略失败,这是非常危险的。所以不管是什么类型都会忽略失败;谨慎使用。【参考方案3】:

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。

【讨论】:

这个答案也非常有用,以防无法编辑 MappingClass 以添加注释 也可以直接用reader.without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)配置ObjectReader 点赞。但是为“with di.xml”添加了一个链接。 (依赖注入.xm):***.com/questions/14343477/…【参考方案4】:

可以通过两种方式实现:

    标记 POJO 以忽略未知属性

    @JsonIgnoreProperties(ignoreUnknown = true)
    

    如下配置对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) 
    

【讨论】:

【参考方案5】:

@JsonIgnoreProperties(ignoreUnknown = true) 对我来说效果很好。我有一个使用 jdk 1.7 在 tomcat 上运行的 java 应用程序。

【讨论】:

也适用于带有 jdk 1.8 的 Spring Boot 应用程序(不需要来自this 答案的第 2 步)【参考方案6】:

如果使用基于 JSON 响应的 pojo 类。如果有可能在 pojo 类级别经常声明 json 更改:

@JsonIgnoreProperties(ignoreUnknown = true)

如果要转换,请在 objectMapper 中添加:

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

这样代码就不会中断。

【讨论】:

【参考方案7】:

从 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 的解决方案保持不变,因此如果您喜欢使用该解决方案,请查看其他答案。

For more information see the 10 minutes Configuration tutorial at:https://github.com/FasterXML/jackson-databind

【讨论】:

【参考方案8】:

确保将 @JsonIgnoreProperties(ignoreUnknown = true) 注释放置到您要作为解析 JSON 响应的结果填充的父 POJO 类,而不是发生从 JSON 到 Java 对象转换的类。

【讨论】:

这种行为有什么特殊原因吗? @tm.sauron 对目标类进行注解是合乎逻辑的,因为您不知道源类中哪些字段是未知的。【参考方案9】:

如上所述,注释仅在父 POJO 类中指定时才有效,而不是在从 JSON 到 Java 对象的转换发生的类中指定。

另一种不接触父类并造成中断的替代方法是仅针对您需要的映射器方法实现您自己的映射器配置。

反序列化功能的包也被移动了。 反序列化Config.FAIL_ON_UNKNOWN_PROPERTIES 到 反序列化Config.Feature.FAIL_ON_UNKNOWN_PROPERTIES

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

【讨论】:

【参考方案10】:

对于正在使用 Spring Boot 的用户,您可以使用 Jackson2ObjectMapperBuilder 配置 Jackson 的默认行为。

例如:

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

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

【讨论】:

【参考方案11】:

我正在使用 jackson-xxx 2.8.5.Maven 依赖,例如:

<dependencies>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.8.5</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.8.5</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.5</version>
    </dependency>

</dependencies>

首先,如果你想全局忽略未知属性。你可以配置ObjectMapper。 如下:

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

如果你想忽略某个类,你可以在你的类上添加注释@JsonIgnoreProperties(ignoreUnknown = true),例如:

@JsonIgnoreProperties(ignoreUnknown = true)
public class E1 

    private String t1;

    public String getT1() 
        return t1;
    

    public void setT1(String t1) 
        this.t1 = t1;
    

【讨论】:

【参考方案12】:

您可以使用 @JsonIgnore 注释 POJO 中的特定属性。

【讨论】:

情况正好相反,例如将 JSON 转换为 POJO,因此无法对属性进行注释(POJO 上不存在) 这并没有回答问题,正如哈迪所说,POJO中没有要注释的字段 这实际上将完全弃权杰克逊 (de) 编组此属性。因此,即使该属性将出现在您的模型中,在通过杰克逊(去)编组时也不会被“考虑”

以上是关于使用 Jackson 忽略 JSON 对象上的新字段 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Jackson 序列化:忽略空值(或 null)

在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性

jackson 常用注解,比如忽略某些属性,驼峰和下划线互转

Jackson序列化生成 json 不同场景下忽略字段

在使用 Jackson 反序列化期间选择性地忽略 JSON 属性

详解jackson注解(三)jackson包含属性、忽略属性的注解