我有一个 java springboot 应用程序。当杰克逊试图反序列化我的请求时,我遇到了错误。我尝试使用 @JsonTypeInfo 和 @JsonSubTypes 但这只会导致不同的错误。我知道我可以只写一个自定义反序列化器,但如果可能的话,我更喜欢使用 jsonsubTypes 和 jsontypeinfo。
我的请求pojo类:
public class QualityControlRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String requestId;
private ComponentType componentType;
private ComponentName componentName;
//setters getters below
组件类型枚举:
public enum ComponentType {
FLOWS("flows"), CRON_JOB("Cron Job");
}
ComponentName接口:
public interface ComponentName {
String getComponentName();
}
ComponentName的第一次实现:
public enum Flows implements ComponentName {
DeleteService("DeleteService", false), CreateService("CreateService", true);
private final String name;
private final boolean internal;
private Flows(String name, boolean internal) {
this.name = name;
this.internal= internal;
}
public String getName() {
return name;
}
public boolean isInternal() {
return isInternal;
}
@Override
public String getComponentName() {
return name;
}
}
ComponentName的第二次实现:
public enum CronJobName implements ComponentName {
UPDATE("The Update"), CLEANUP("The Cleanup");
public final String name;
private CronJobName(String name) {
this.name = name;
}
public String toString() {
return name;
}
public String getName() {
return name;
}
@Override
public String getComponentName() {
return name;
}
}
API类:
@Path("/")
@Component
public class QualityControlRest {
@POST
@Path("/report/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Response report(@Valid QualityControlRequest request) {
logger.debug("Received a request");
//does something
}
}
当它对 /report 进行 rest 调用时,请求看起来像这样:
{ “requestId”:“123456”, “组件类型”:“CRON_JOB”, “组件名称”:“清理” }
我会得到以下错误:
无法构造
的实例(不存在 Creator,如默认构造函数):抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么包含额外的类型信息 在 [来源:(org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream);行:1,列:69](通过参考链:org.onap.so.qualitycontrol.beans.QualityControlRequest["componentName"])org.onap.so.qualitycontrol.beans.ComponentName
我明白为什么我得到这个,因为杰克逊也不知道哪个集中(实现)来反序列化 ComponentName。 因此,为了解决这个问题,我将 @JsonTypeInfo 添加到我的 ComponentName 接口中。所以接口类现在看起来像这样:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "componentType",
defaultImpl = CronJobName.class)
@JsonSubTypes({@JsonSubTypes.Type(value = CronJobName.class, name = "CRON_JOB"),
@JsonSubTypes.Type(value = Flows.class, name = "FLOWS")})
public interface ComponentName {
String getComponentName();
}
所以我告诉它使用 componentType 来确定要使用的 impl。现在,当它对 /report 进行 rest 调用时,json 看起来像这样:
{ “requestId”:“12345”, “组件类型”:“CRON_JOB”, “组件名称”:[“CRON_JOB”,“HEATBRIDGE”] }
这似乎有助于修复第一个杰克逊错误,但现在它失败了:
[无法从 START_ARRAY 令牌中反序列化
的实例 在 [来源:(org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream);行:1,列:69](通过参考链:org.onap.so.qualitycontrol.beans.QualityControlRequest["componentName"])]org.onap.so.db.beans.CronJobName
我认为这是因为 componentName 现在是一个 json 数组,它无法将其反序列化为枚举类型 CronJobName。我想我可能只是在这里遗漏了一些很小的东西。任何建议或帮助将不胜感激。