需求背景
第三方服務返回的響應報文是JSON,但是,我們只對其中的一部分感興趣,故反序列化時創建實體無需包含JSON中的全部字段。
如反序列化"{"name":"JSON","age":"23","address":"北京市西城區","day":1633688895637}"的時候,實體類中唯獨沒有age字段時,系統拋出的異常如下:
Parse object to Object error
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "age" (class dto.StudentTest), not marked as ignorable (3 known properties: "name", "address", "day"])
at [Source: (String)"{"name":"JSON","age":"23","address":"北京市西城區","day":1633688895637}"; line: 1, column: 23] (through reference chain: com.cloud.isavana.media.module.report.dto.StudentTest["age"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:987)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1974)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1701)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1679)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:330)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516)
問題分析
Jackson反序列化JSON字符串的時候,出現這種問題是由於JSON里面包含了實體沒有的字段導致反序列化失敗。
問題解決
使用注解@JsonIgnoreProperties
在需要轉化的對象的類中添加注解@JsonIgnoreProperties(ignoreUnknown = true),示例如下:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
/**
* @Author: Wiener
* @Date: 2021/10/8 17:02
*/
@Getter
@Setter
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class StudentTest implements Serializable {
private static final long serialVersionUID = -5246589941647210011L;
//姓名
private String name;
//年齡
// private String age;
//住址
private String address;
private Date day;
}
ObjectMapper對象配置FAIL_ON_UNKNOWN_PROPERTIES
String str="{\"name\":\"JSON\",\"age\":\"29\",\"address\":\"北京市朝陽區\",\"addressTest\":\"無對應屬性,不轉換\"}";;
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
StudentTest value = mapper.readValue(str, StudentTest.class);
System.out.println(value);
Reference
分享一句俗語:男兒斷掌千斤兩,女子斷掌過房養。
