当前位置: 首页 > 知识库问答 >
问题:

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

章涵蓄
2023-03-14

如何用jackson(Java)反序列化Object中的json对象(在我的例子中,当前字段中提供对象)?

输入字符串:

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

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,我有一个java。时间ZoneDateTime提供对象中。

{“author”:“Peter Smith”,“previous”:“null”,“current”:{“id”:“00Yno9WwsL”,“authorUserId”:“foo”,“createdAt”:{“offset”:{“totalSeconds”:0,“id”:“Z”,“rules”:{“transitionRules”:[],“fixedOffset”:true},“dayOfWeek”:[],“transitions],“fixedOffset”:11”,“dayOfWeek:“SUNDAY”;“dayOfYear”;“true”;“true},“zone”;“zone”;“zone”;“zone”;“zone”:“UTC”;“规则”:“{“transitions”;“transitions”;“{“transitions”;“transitions”;“{“,“nano”:0,“second”:0,“monthValue”:2,“年表”:{“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,我添加Offerclass。

@Slf4j
@Data
@NoArgsConstructor
public class Offer {

    @Id
    protected String id;

    protected String authorUserId;

    protected ZonedDateTime createdAt;

}

共有2个答案

万俟小林
2023-03-14

错误消息告诉您问题是什么:“我们希望字段名开头有双引号”。

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

提示:只需使用以下命令序列化演示对象,即可生成已知良好数据:

new ObjectMapper().writeValueAsString(demoObject);

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

苏骏
2023-03-14
匿名用户

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

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

您尝试将LinkedHashMap读入报价失败,因为您(隐式地)使用了LinkedHashMap的toString表示来解析未生成有效JSON的内容。

编辑4答案:,如果对象包含ZoneDateTime。在写入和读取时使用此选项:

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

 类似资料:
  • 我目前正在开发一个Java web应用程序,它使用Magento REST API公开的JSON数据。api返回的数据示例如下: 我的应用程序中有一个Java类,如下所示: 我想对数据进行反序列化,并将其转换为,但我总是得到以下错误: 这是我用来将JSON响应反序列化为ArrayList的语句行: 有人能分享一些见解吗?我看到一些例子,返回的JSON对象前面没有任何ID。那是因为我做错了什么吗?非

  • 我有一个JSON,它带有一个包含任意键和值类型的标记,我想将其读入Java中POJO内的映射。映射将是指向JsonValue或JsonNode之类的字符串。我正在使用对象映射器解析json。 有人对如何设置我的POJO来与杰克逊一起完成这一任务有什么建议吗?还是一种更好的方式? Json示例: 映射方法: 我的POJO:

  • 试图将JSON反序列化为我创建的Java bean。对杰克逊和这项努力来说真的很新鲜,所以请容忍我。我有以下几点: 由于JSON中的对象被反复使用,我的Java Bean被分解为几个部分,因此: ...和以类似方式实现的另一个BlockBean类(为简洁起见省略)。我使用杰克逊来完成这个任务,我的问题是——杰克逊中是否有序列化和反序列化的机制?理想情况下,我想要这样的东西(下面是伪代码,因为我无法

  • 鉴于这种反应: 我怎样才能将数据属性反序列化为像这样的 MapDTO 我已经尝试使用自定义反序列化器,但是按名称获取所有属性,然后基于这些属性和嵌套对象创建一个新的MapDTO对象看起来很麻烦。如果结构发生变化,我必须更改反序列化器和DTO本身。让Jackson从给定的根开始进行反序列化会更容易。我使用Jackson 2.12.4到ResAs的4.4.0。我想避免创建不必要的包装类。

  • 我有一个具有名称字段的界面,如下所示: 然后我会得到HTTP 400错误请求错误代码,其中包含以下异常日志: 抽象类型只能用附加类型信息实例化 模块的层次结构是模块B依赖于模块a。我尝试使用@JsonTypeInfo,但模块之间的依赖关系是一个限制,不允许我在@JsonSubtypes注释中为类C中的字段f使用BField.class。

  • 我有一个杰克逊多态性问题。我想将JSON数据反序列化为多态类型。通过阅读Jackson文档,我可以将JSON数据反序列化为多态类型。不过,我有一个特例。我有一个类结构如下: 注意:类栏除了继承的“类型”字段之外没有任何其他成员变量。 如果我传入上面的json数据,如: 我得到了类似“无法从end_token中反序列化类条”的信息。我相信这是因为JsonTypeInfo和JsonSubTypes注释