簡體   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