Jackson java.util.Optional 序列化不包括类型 ID
Jackson java.util.Optional serialization does not include type ID
我得到以下 类:
@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,序列化在 Spring 提供 RESTful 网络服务的启动应用程序中完成。
编辑: 这是 Spring REST 方法 returns Optional
:
@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
:
Error while extracting response for type [class com.example.demo.MySubEntity] and content type [application/json;charset=UTF-8]; nested exception is 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'; nested exception is 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'
这确实看起来像一个错误。对于这种情况,我可以建议一种解决方法,即使用 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;
}
}
我得到以下 类:
@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,序列化在 Spring 提供 RESTful 网络服务的启动应用程序中完成。
编辑: 这是 Spring REST 方法 returns Optional
:
@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
:
Error while extracting response for type [class com.example.demo.MySubEntity] and content type [application/json;charset=UTF-8]; nested exception is 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'; nested exception is 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'
这确实看起来像一个错误。对于这种情况,我可以建议一种解决方法,即使用 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;
}
}