Jackson - 自定义反序列化器不会读取 JSON 中的所有字段
Posted
技术标签:
【中文标题】Jackson - 自定义反序列化器不会读取 JSON 中的所有字段【英文标题】:Jackson - Custom Deserializer doesn't read all the fields in JSON 【发布时间】:2020-04-30 13:07:09 【问题描述】:我从 API 接收到这个 JSON:
"link": [],
"firstRecord": 1,
"item": [
"Customer":
"id": "1058207",
"firstName": "foo",
"lastName": "foo2",
"nestedObj1":
"id": "40008"
,
"nestedObj2":
"link": [],
"linkfoo": "lala",
"item": [
"id": "266614",
"label": "NESTED_OBJ_2"
]
]
我的反序列化函数
@Override
public CustomerView deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException
//tried this too
TreeNode treeNode = p.getCodec().readTree(p);
// also this
JsonNode node = p.getCodec().readTree(p);
JsonNode simpleNode = new ObjectMapper().readTree(p);
// use for each field that is not String
ObjectMapper mapper = new ObjectMapper();
Customer customer = new Customer();
customer.setFirstName(simpleNode.get("Customer").get("firstName").textValue());
NestedObj2[] arrayObj2 = mapper.readValue(
simpleNode.get("Customer").get("nestedObj2").get("item").toString(),
NestedObj2[].class);
customer.setArrayObj2(arrayObj2);
类 NestedObj2 具有 JSON 中的所有字段,“item”数组是作为字段的单独对象。
问题是,JsonNode 和 TreeNode 都没有看到字段“nestedObj2”,但其余字段在反序列化时都在其中 -> 在调试时检查。
我是否遗漏了配置中的某些内容,还是应该使用其他对象来反序列化?
谢谢!
编辑
最后,我按照@Mehrdad HosseinNejad 的建议使用了 DTO。
当我通过RestTemplate.exchange()
接收这个 JSON 时,我必须像这里 https://***.com/a/9381832/12677470 一样配置 RestTemplate
和 MappingJacksonHttpMessageConverter
。
【问题讨论】:
【参考方案1】:使用 DTO 类可能是一个更好的主意,无需创建自定义反序列化器
我编写了一个示例嵌套 DTO,如下所示
为客户创建 DTO 类
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Customer
private Long id;
private String firstName;
private String lastName;
private NestedObj1 nestedObj1;
private NestedObj2 nestedObj2;
//getter and setter
为 NestedObj1 创建 DTO 类
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class NestedObj1
private Long id;
//getter and setter
为 NestedObj2 创建 DTO 类
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class NestedObj2
private List<String> link;
private String linkFoo;
private List<Item> item;
//getter and setter
为 Item 创建 DTO 类
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Item
private Long id;
private String label;
//getter and setter
创建这些 DTO 后,您可以简单地使用 ObjectMapper 类 将您的 JSON 转换为 Java 对象
Customer customer= new ObjectMapper().readValue(jsonFile, Customer.class);
有关忽略某些属性等更多选项,...您可以使用以下链接:
Jackson Annotation Examples
反序列化中的更多信息:
Getting Started with Deserialization in Jackson
【讨论】:
感谢您的回答!问题是,这个 json 有更多的字段,我不想放入我的 POJO,这就是我使用自定义反序列化器的原因。无论如何,我有你上面写的 DTO,但是反序列化器本身(JsonNode)在它的映射中没有字段'nestedObj2'。我正在寻找解决方案,发生了什么 如果您不想将任何 JSON 属性放入 POJO,您可以将 @JsonIgnore 放在该属性上以忽略它!。或者您可以从 POJO 中删除该属性(例如,如果您不想进行 id 转换,最好从 Item 类中删除它) ***.com/questions/38077728/… 最后我使用了没有反序列化器的正确 DTO。谢谢!以上是关于Jackson - 自定义反序列化器不会读取 JSON 中的所有字段的主要内容,如果未能解决你的问题,请参考以下文章
当值为“null”时,Jackson 忽略自定义字段反序列化器
Jackson 将 YAML 文件反序列化为 Map(没有自定义反序列化器)
如何让Jackson JSON生成的数据包含的中文以unicode方式编码