为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 jackson(Java) 反序列化对象中的 json 对象?

如何使用 jackson(Java) 反序列化对象中的 json 对象?

胡子哥哥 2023-04-13 14:15:41
如何使用 jackson(Java) 反序列化对象中的 json 对象(在我的例子中,对象Offer存在于current字段中)?输入字符串:message.getMessage();{"header":"OFFER","message":"{\"author\":\"Peter Smith\",\"previous\":null,\"current\":{\"id\":\ "eOUQieQdvB\",\"authorUserId\":\"foo\"}}"}ObjectMapper mapper = new ObjectMapper();PushEventMessage<PushEvent<Offer>> pushEventMessage = mapper.readValue(message.getMessage(), PushEventMessage.class);pushEventMessage.getMessage();{"author":"Peter Smith","previous":null,"current":{"id":"eOUQieQdvB","authorUserId":"foo"}}PushEvent<Offer> pushEvent = mapper.readValue(pushEventMessage.getMessage(), PushEvent.class);pushEvent.getAuthor(); // is OK and contain "Peter Smith"pushEvent.getCurrent() // is KO and contain {id=eOUQieQdvB, authorUserId=foo}我想反序列化:Offer offer= mapper.readValue(pushEvent.getCurrent() + "", Offer.class);我的错误是:com.fasterxml.jackson.core.JsonParseException: Unexpected character ('i' (code 105)): was expecting double-quote to start field name at [Source: (String)"{id=eOUQieQdvB, authorUserId=foo,编辑 1,我添加PushEvent<T>类。import lombok.*;@Data@Builder@AllArgsConstructor@NoArgsConstructor@ToStringpublic class PushEvent<T> {    String author;    T previous;    T current;    String error;}编辑 2,我试试这个,但结果是一样的PushEvent<Offer> pushEvent = mapper.readValue(pushEventMessage.getMessage().replaceAll("\\\"", "\""), PushEvent.class);我采用@Smutje 的解决方案,这解决了第一个问题。!!编辑 3,我有一个java.time.ZonedDateTime对象Offer。{"author":"Peter Smith","previous":null,"current":{"id":"00Yno9WwsL","authorUserId":"foo","createdAt":{"offset":{"totalSeconds" :0,"id":"Z","rules":{"transitionRules":[],"transitions":[],"fixedOffset":true}},"zone":{"id":"UTC" “规则”:{“transitionRules”:[],“transitions”:[],“fixedOffset”:true}},“dayOfMonth”:11,“dayOfWeek”:“SUNDAY”,“dayOfYear”:42,“month” ":"二月","年":2018,"小时":1,"分钟":0,"纳米":0,"秒":0,"月值":2,"年表":{"id" :“国际标准化组织”,“日历类型":"iso8601"}}}}
查看完整描述

2 回答

?
达令说

TA贡献1821条经验 获得超6个赞

由于许多映射框架无法使用泛型或继承层次结构正确反序列化对象,因此以下内容很难看但应该是可能的


PushEvent<Offer> pushEvent = mapper.readValue(pushEventMessage.getMessage(), PushEvent.class);

String serializedOffer = mapper.writeValueAsString(pushEventMessage.getCurrent());

Offer offer = mapper.readValue(serializedOffer, Offer.class);

pushEvent.setCurrent(offer);

说明:Jackson 反序列化您的内部对象Offer,而不是像您所说的那样反序列化,而是LinkedHashMap在将 JSON 对象读取为 actual 之前再次将其序列化为 JSON 对象Offer。


您尝试将 the 读LinkedHashMap入 aOffer失败,因为您(隐含地)使用了toString的表示来LinkedHashMap解析它不会产生有效的 JSON。


编辑 4 答案:,如果对象包含一个ZonedDateTime. 写入和读取时使用它:


ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

mapper.setDateFormat(new StdDateFormat());


查看完整回答
反对 回复 2023-04-13
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

错误消息告诉您问题是什么:“期望双引号开始字段名称”。

从简短的检查来看,您读取 json 字符串的代码看起来是正确的,因此请确保为其提供有效数据。

提示:您可以通过简单地序列化一个演示对象来生成已知的良好数据:

new ObjectMapper().writeValueAsString(demoObject);

然后您可以尝试使用该字符串运行您的代码,这将告诉您您的输入是否有效。


查看完整回答
反对 回复 2023-04-13
  • 2 回答
  • 0 关注
  • 121 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信