【问题标题】:Jackson java.util.Optional serialization does not include type IDJackson java.util.Optional 序列化不包括类型 ID
【发布时间】:2018-08-10 18:55:54
【问题描述】:

我有以下课程:

@JsonIdentityInfo(
    generator = ObjectIdGenerators.IntSequenceGenerator.class,
    property = "oid"
)
@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "clazz")
@JsonSubTypes({
    @JsonSubTypes.Type(value = MySubEntity.class, name = "MySubEntity"),
})
public abstract class Entity {
    ...
}

public class MySubEntity extends Entity {
    ...
}

现在,当我序列化包装在 Optional 中的 MySubEntity 时,JSON 不包含包含类型 ID 的 clazz 属性。 错误?当我序列化到 List<MySubEntity> 或只是到 MySubEntity 时,它工作正常。

设置:jackson-databind 2.9.4,jackson-datatype-jdk8 2.9.4,序列化在提供 RESTful Web 服务的 Spring Boot 应用程序中完成。

编辑:这是返回 Optional 的 Spring REST 方法:

@RequestMapping(method = RequestMethod.GET, value = "/{uuid}", produces = "application/json")
public Optional<MySubEntity> findByUuid(@PathVariable("uuid") String uuid) {
    ...
}

编辑:made a SSCCE 带有一个简单的 Spring REST 控制器和两个测试。第一个测试是直接使用ObjectMapper,尽管缺少clazz,但反序列化是成功的。第二个测试调用 REST 控制器并失败并出现错误,因为缺少 clazz

提取类型 [class com.example.demo.MySubEntity] 和内容类型 [application/json;charset=UTF-8] 的响应时出错;嵌套异常是 org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Missing type id when trying to resolve subtype of [simple type, class com.example.demo.MySubEntity]: missing type id property 'clazz';嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class com.example.demo.MySubEntity]: missing type id property 'clazz'

【问题讨论】:

  • 澄清一下,您是想将实体序列化为 JSON 还是从 JSON 反序列化?
  • @SergiiBishyr 我两者都做。我的 Spring REST Web 服务正在生成 JSON,而我的客户端应用程序正在使用它。模型类在服务器和客户端之间共享。
  • 你使用spring-boot吗?尝试从依赖项中删除版本。在 pom.xml 中将 spring-boot-starter-parent 作为父级或 BOM 应该可以解决依赖项的正确版本。使用完全相同的控制器,我得到的响应是{"clazz":"MySubEntity","oid":1}
  • 能否请您发布收到的json 回复?
  • @SergiiBishyr 我添加了一个 SSCCE。如果你有时间可以试试。只需调用 gradle build 的测试任务即可。

标签: spring jackson jackson-databind


【解决方案1】:

这确实看起来像一个错误。对于这种情况,我可以建议一种解决方法,即使用JsonTypeInfo.As.EXISTING_PROPERTY 并将字段clazz 添加到您的Entity。这种方法只有一种情况是 clazz 必须在 java 代码中手动设置。然而,这很容易克服。 以下是建议解决方法的完整代码:

@JsonIdentityInfo(
        generator = ObjectIdGenerators.IntSequenceGenerator.class,
        property = "oid"
)
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY, //field must be present in the POJO
        property = "clazz")
@JsonSubTypes({
        @JsonSubTypes.Type(value = MySubEntity.class, name = "MySubEntity"),
})
public abstract class Entity {

    @JsonProperty
    private String uuid;

    //Here we have to initialize this field manually.
    //Here is the simple workaround to initialize in automatically
    @JsonProperty
    private String clazz = this.getClass().getSimpleName();

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }
}

【讨论】:

  • 很高兴您能确认该错误并找到解决方法。谢谢!我将尝试在 github jackson-datatype-jdk8 项目上打开一个问题。
  • @SteffenHarbich jackson-datatype-jdk8 项目已弃用并移至 jackson-modules-java8。但是,由于对我的依赖,我仍然可以重现该问题。所以继续打开问题! :)
  • @SteffenHarbich 似乎在这里打开了这样一个问题:github.com/FasterXML/jackson-modules-java8/issues/44
猜你喜欢
  • 1970-01-01
  • 2019-05-17
  • 2014-10-06
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
相关资源
最近更新 更多