繁体   English   中英

ObjectMapper无法处理带有遗留枚举(类)的映射对象

[英]ObjectMapper can't handle mapping object with legacy enums (classes)

我遇到了为某些遗留代码构建REST架构的问题。 Jackson ObjectMapper无法将我的自定义对象映射到旧对象,因为“枚举”实际上是具有静态最终字段的类。

我尝试实现自定义转换器/反序列化器但没有成功

在遗留系统中,存在如下所示的枚举:

public final class LegacyEnum extends LegacyEnumSuperclass {

    public static final LegacyEnum VALUE = new LegacyEnum("1");

我收到这些'enums'的值作为字符串,我转换为遗留枚举值(自定义反序列化器)并将它们设置在我的自定义类中(我需要它,因为我使用的是jackson注释,我无法访问或许可修改遗留代码)这部分工作得很好。 当我尝试将自定义对象映射到旧对象时

objectMapper.convertValue(myCustomObject, LegacyObjectContainingEnums.class); 

我得到一个例外:

Can not construct instance of LegacyEnum: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)

LegacyEnum类有一个私有构造函数,而LegacyEnumSuperclass有一个类似的受保护构造函数,因此我无法访问它们(ObjectMapper也不能)。 我已经尝试实现一个自定义转换器,它会跳过ObjectMapper映射的“创建新对象”部分,我也尝试重用我的自定义反序列化器。 我遇到了多个问题而没有成功。

最令人讨厌的部分是,当我使用ModelMapper库时,它就像一个魅力(它可能只是在遗留对象中设置一个值,不需要像ObjectMapper那样创建新的LegacyEnum实例!)但是我试图解决这个问题而不用添加新的依赖项。

有任何想法吗?

我通过使用MixIn和自定义反序列化器解决了这个问题,如下所示:

public abstract class LegacyClassMixIn 
    @JsonDeserialize(using = LegacyEnumDeserializer.class)
    abstract LegacyEnum getLegacyEnum();

解串器:

public class LegacyEnumDeserializer extends JsonDeserializer<LegacyEnumSuperclass> implements ContextualDeserializer {

private JavaType valueType;

@Override
public JsonDeserializer createContextual(DeserializationContext context, BeanProperty property) {
    JavaType wrapperType = property.getType();
    LegacyEnumDeserializer deserializer = new LegacyEnumDeserializer();
    deserializer.valueType = wrapperType;

    return deserializer;
}

@Override
public LegacyEnumSuperclass deserialize(JsonParser parser, DeserializationContext context) throws IOException {
    return LegacyEnumSuperclass.getEnum(valueType.getRawClass(), parser.readValueAs(String.class));
}

valueType.getRawClass()返回LegacyEnum.class,这样我就可以为继承LegacyEnumSuperclass类的所有“枚举”使用一个反序列化器。 getEnum是遗留代码中的一种自定义方法。

在ObjectMapper中注册MixIn Spring配置:

@Configuration
public class ObjectMapperConfig {

    public ObjectMapperConfig(ObjectMapper objectMapper) {
        objectMapper.addMixIn(LegacyClass.class, LegacyClassMixIn.class);
    }
}

这样我可以使用LegacyClass作为Controller方法中的参数。 谢谢你的线索。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM