[英]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. 你试图读取
LinkedHashMap
到Offer
,因为你(隐含)使用不合格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.