泛型类反序列化的问题

时间:2020-10-24 16:58:55

标签: java spring generics jackson polymorphism

我最近遇到了GenericsJackson的问题,最终没有使用它。 我有一个界面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的方法。

1 个答案:

答案 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 参数。

相关问题