繁体   English   中英

如何使用Jackson(Java)在Object中反序列化JSON Object?

[英]How to deserialize json Object in Object with jackson(Java)?

如何使用jackson(Java)反序列化Object中的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
@ToString
public class PushEvent<T> {
    String author;
    T previous;
    T current;
    String error;
}

编辑2 ,我尝试这样做,但结果是相同的

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

我采用@Smutje的解决方案,此解决了第一个问题。 !!

编辑3 ,我在Offer对象中有一个java.time.ZonedDateTime

{“ author”:“ Peter Smith”,“ previous”:null,“ current”:{“ id”:“ 00Yno9WwsL”,“ authorUserId”:“ foo”,“ createdAt”:{“ offset”:{“ totalSeconds” :0,“ id”:“ Z”,“ rules”:{“ transitionRules”:[],“ transitions”:[],“ fixedOffset”:true}},“ zone”:{“ id”:“ UTC” ,“ rules”:{“ transitionRules”:[],“ transitions”:[],“ fixedOffset”:true}},“ dayOfMonth”:11,“ dayOfWeek”:“ SUNDAY”,“ dayOfYear”:42,“ month “:” FEBRUARY“,” year“:2018,” hour“:1,” minute“:0,” nano“:0,” second“:0,” monthValue“:2,” chronology“:{” id“ :“ ISO”,“ calendarType”:“ iso8601”}}}}

我有这个错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.ZonedDateTime` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"id":"00Yno9WwsL","authorUserId":"foo", ....."createdAt":{"offset":{"totalSeconds":0,...

编辑4 ,我添加了Offer类。

@Slf4j
@Data
@NoArgsConstructor
public class Offer {

    @Id
    protected String id;

    protected String authorUserId;

    protected ZonedDateTime createdAt;

}

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

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序列化,该LinkedHashMap在将JSON对象读取为实际Offer之前再次被序列化为JSON对象。

你试图读取LinkedHashMapOffer ,因为你(隐含)使用不合格toString的表示LinkedHashMap解析产生有效的JSON。

编辑4答案:如果Object包含ZonedDateTime 读写时使用此:

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

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

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

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

new ObjectMapper().writeValueAsString(demoObject);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM