【问题标题】:Dealing with Jackson Deserialization with JsonTypeInfo.Id.NAME使用 JsonTypeInfo.Id.NAME 处理 Jackson 反序列化
【发布时间】:2020-06-27 18:00:33
【问题描述】:

当我使用配置为的 ObjectMapper 时:

        DefaultTyping applicability = ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT;
        TypeResolverBuilder<?> typer = DefaultTypeResolverBuilder.construct(applicability, validator);
        String propertyName = "type";
        typer = typer.init(JsonTypeInfo.Id.NAME, null);
        typer = typer.inclusion(JsonTypeInfo.As.PROPERTY);
        typer = typer.typeProperty(propertyName);

        ObjectMapper mapper=new ObjectMapper();
        mapper.setDefaultTyping(typer);

它会产生类似的 JSON:

 {
   "type": "ShortClassName",
   ...
 }

该类型没有预期的完整包名。但是尝试使用此对象映射器进行反序列化会导致:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException

如何将基本包名称指定为对象映射器配置的一部分,以便序列化的 JSON 只有类名?

【问题讨论】:

    标签: java json jackson json-deserialization


    【解决方案1】:

    您可以通过使用mapper.readerFor(...) 并指定要提取的类型来为特定对象创建映射器,在这种情况下是

    ObjectReader shortClassNameReader = mapper.readerFor(new TypeReference<ShortClassName>(){})
    

    ShortClassName 是您的班级名称。

    然后您可以使用 ObjectReaderreadValue 来反序列化 JSON。

    【讨论】:

    • 在 Spring MVC 的上下文中,有没有办法全局设置这个,以便控制器方法可以使用类型引用集从 JSON 生成对象?
    • 好吧,我相信,如果控制器方法的参数类型正确(在本例中为 ShortClassName),Spring MVC 应该会自动执行此操作。但是你可能应该使用杰克逊的注释,特别是@JsonTypeInfo(参见logicbig.com/tutorials/misc/jackson/…)。然后 - 我认为 - Spring 会使用这个注释。
    【解决方案2】:

    谢谢 Ayk - 如果类名本身就是要反序列化的类名,但如果它嵌套在另一个类的 JSON 中,则它不起作用。然而,我通过定义一个自定义的typeIdResolver 来实现它,它分别在idFromValuetypeFromId 中将ID 从/到对象转换。这样就可以在全局范围内工作,而无需对序列化中涉及的每个对象进行注释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 2013-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多