简体   繁体   English

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

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

How to deserialize json Object ( Offer object present in current field in my case) in Object with jackson(Java)? 如何使用jackson(Java)反序列化Object中的json对象(在我的情况下, Offer对象存在于current字段中)?

input String: 输入字符串:

message.getMessage();

{"header":"OFFER","message":"{\\"author\\":\\"Peter Smith\\",\\"previous\\":null,\\"current\\":{\\"id\\":\\"eOUQieQdvB\\",\\"authorUserId\\":\\"foo\\"}}"} {“ 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"}} {“ 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}

I want deserialize: 我想反序列化:

Offer offer= mapper.readValue(pushEvent.getCurrent() + "", Offer.class);

My error is: 我的错误是:

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,

EDIT 1 , I add PushEvent<T> class. 编辑1 ,我添加PushEvent<T>类。

import lombok.*;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class PushEvent<T> {
    String author;
    T previous;
    T current;
    String error;
}

EDIT 2 , I try this but the result is the same 编辑2 ,我尝试这样做,但结果是相同的

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

I take the solution of @Smutje and this fix the 1st problem. 我采用@Smutje的解决方案,此解决了第一个问题。 !! !!

EDIT 3 , I have a java.time.ZonedDateTime in Offer object. 编辑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"}}}} {“ 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”}}}}

I have this error: 我有这个错误:

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,...

EDIT 4 , I add Offer class. 编辑4 ,我添加了Offer类。

@Slf4j
@Data
@NoArgsConstructor
public class Offer {

    @Id
    protected String id;

    protected String authorUserId;

    protected ZonedDateTime createdAt;

}

Due to the inability of many mapping frameworks to properly deserialize objects using generics or inheritance hierarchies the following is ugly but should be possible 由于许多映射框架无法使用泛型或继承层次结构正确地反序列化对象,因此以下情况很难看,但应该可行

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);

Explanation: Jackson deserializes your inner object not as Offer as you stated it but rather as a LinkedHashMap which is being serialized as a JSON object again before reading the JSON object as actual Offer . 说明:Jackson会将您的内部对象反序列化,而不是像您所说的那样作为Offer反序列化,而是作为LinkedHashMap序列化,该LinkedHashMap在将JSON对象读取为实际Offer之前再次被序列化为JSON对象。

Your attempt to read the LinkedHashMap into a Offer failed because you (implicitely) used the toString representation of LinkedHashMap to parse which does not produce valid JSON. 你试图读取LinkedHashMapOffer ,因为你(隐含)使用不合格toString的表示LinkedHashMap解析产生有效的JSON。

EDIT 4 answer: , if Object contain a ZonedDateTime . 编辑4答案:如果Object包含ZonedDateTime Use this when write and read: 读写时使用此:

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

The error message tells you what the problem is: "was expecting double-quote to start field name". 该错误消息告诉您问题是什么:“期望双引号开始字段名”。

From a brief inspection, your code to read the json string looks correct, so make sure you are providing it with valid data. 从简短的检查中,您读取json字符串的代码看起来正确,因此请确保为它提供有效数据。

Hint: you can generate known good data by simply serialising a demo object with: 提示:您可以通过简单地序列化演示对象来生成已知的良好数据:

new ObjectMapper().writeValueAsString(demoObject);

You can then try to run your code with that string, and this will tell you if your input is valid or not. 然后,您可以尝试使用该字符串运行代码,这将告诉您输入是否有效。

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

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