我最近遇到了Generics
和Jackson
的问题,最终没有使用它。
我有一个界面MonetaryType
:
public interface MonetaryType implements Serializable {}
由多个enum
实现,例如:
public enum IncomeType implements MonetaryType {
FULL_TIME_SALARY,
PART_TIME_SALARY,
CHILD_BENEFIT
}
public enum ExpenseType implements MonetaryType {
HEAT,
CONDO_FEES,
ELECTRICITY
}
我创建了一个通用类:
public MonetaryValidation<T extends MonetaryType> {
private T monetaryType;
private boolean isPassed;
private String message;
// Getters and Setters
}
Jackson库未反序列化此对象。这意味着,如果在有效负载包含MonetaryValidation
对象的同时调用任何Spring REST端点,它将抛出以下异常:
java.lang.IllegalArgumentException:无法构造的实例
**.enumeration.MonetaryType
(没有创建者,例如默认构造, 存在):抽象类型要么需要映射到具体类型, 具有自定义反序列化器,或包含其他类型信息
我不想用Jackson polymorphic deserialization approach解决此问题,因为据我所知,它要求客户端传递一个额外的标志来指定接口或抽象类的具体实现。
不幸的是,我最终创建了多个非通用MonetaryValidation
的子类(每个MonetaryType
子类一个子类),我知道这不是一个不错的解决方案。
非常感谢您能帮助我了解问题出在哪里,以及是否不需要在传递额外字段时使用@JsonSubTypes
的方法。
答案 0 :(得分:0)
有一个想法,尝试接受 monetaryType 作为 String 类型参数,然后可以在 Generic 类中自定义转换器以处理通用类型字段,例如:
public void setMonetaryType(String monetaryType) {
Optional<IncomeType> incomeType = Arrays.stream(IncomeType.values()).filter(i -> i.name().equals(monetaryType)).findFirst();
incomeType.ifPresent(i -> {
this.monetaryType = (T)i;
});
Optional<ExpenseType> expenseType = Arrays.stream(ExpenseType.values()).filter(i -> i.name().equals(monetaryType)).findFirst();
expenseType.ifPresent(i -> {
this.monetaryType = (T)i;
});
}
我认为这是除使用JsonSubTypes
或自定义转换器以外的一种简单方法,因为它实际上是一个 generic 参数。