【发布时间】:2011-07-24 05:22:59
【问题描述】:
我正在使用 Jackson JSON 库将一些 JSON 对象转换为 android 应用程序上的 POJO 类。问题是,在发布应用程序时,JSON 对象可能会更改并添加新字段,但目前即使添加了简单的 String 字段,它也会中断,可以安全地忽略它。
有没有办法告诉杰克逊忽略新添加的字段? (例如 POJO 对象上不存在)?全局忽略会很棒。
【问题讨论】:
我正在使用 Jackson JSON 库将一些 JSON 对象转换为 android 应用程序上的 POJO 类。问题是,在发布应用程序时,JSON 对象可能会更改并添加新字段,但目前即使添加了简单的 String 字段,它也会中断,可以安全地忽略它。
有没有办法告诉杰克逊忽略新添加的字段? (例如 POJO 对象上不存在)?全局忽略会很棒。
【问题讨论】:
Jackson 提供了一个可以在类级别使用的注解 (JsonIgnoreProperties)。
将以下内容添加到类的顶部(不添加到单个方法):
@JsonIgnoreProperties(ignoreUnknown = true)
public class Foo {
...
}
根据您使用的杰克逊版本,您必须在当前版本中使用不同的导入:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
在旧版本中是这样的:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
【讨论】:
com.fasterxml.jackson.annotation.JsonIgnoreProperties,它对我不起作用。有什么想法吗?
com.fasterxml.jackson.annotation.JsonIgnoreProperties 导入工作
除了已经提到的 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);
这是在没有注释的情况下使用的默认值,可以方便的回退。
【讨论】:
ObjectMapper。
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。
【讨论】:
reader.without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)配置ObjectReader
可以通过两种方式实现:
标记 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)
【讨论】:
@JsonIgnoreProperties(ignoreUnknown = true)
对我来说效果很好。我有一个使用 jdk 1.7 在 tomcat 上运行的 java 应用程序。
【讨论】:
如果使用基于 JSON 响应的 pojo 类。如果有可能在 pojo 类级别经常声明 json 更改:
@JsonIgnoreProperties(ignoreUnknown = true)
如果要转换,请在 objectMapper 中添加:
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
这样代码就不会中断。
【讨论】:
从 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
【讨论】:
确保将 @JsonIgnoreProperties(ignoreUnknown = true) 注释放置到您要作为解析 JSON 响应的结果填充的父 POJO 类,而不是发生从 JSON 到 Java 对象转换的类。
【讨论】:
如上所述,注释仅在父 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);
【讨论】:
对于正在使用 Spring Boot 的用户,您可以使用 Jackson2ObjectMapperBuilder 配置 Jackson 的默认行为。
例如:
@Bean
public Jackson2ObjectMapperBuilder configureObjectMapper() {
Jackson2ObjectMapperBuilder oMapper = new Jackson2ObjectMapperBuilder();
oMapper.failOnUnknownProperties(false);
return oMapper;
}
然后你可以在任何你需要的地方自动装配ObjectMapper(默认情况下,这个对象映射器也将用于http内容转换)。
【讨论】:
我正在使用 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;
}
}
【讨论】:
您可以使用 @JsonIgnore 注释 POJO 中的特定属性。
【讨论】: