ObjectMapper不能处理与传统枚举映射对象(类)

问题描述 投票:3回答:1

我在与建设REST架构对于一些遗留代码的问题。杰克逊ObjectMapper无法映射,因为“枚举”,真正是类的静态最终字段我的自定义对象遗留对象。

我尝试没有成功实现自定义转换器/解串器

在传统系统中有枚举看起来像这样:

public final class LegacyEnum extends LegacyEnumSuperclass {

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

我收到这些“枚举”作为字符串值,我转换成传统枚举值(自定义解串器),并设定他们在我的自定义类(我需要它,因为我使用的是杰克逊的注解,我没有访问或许可修改遗留代码),这部分工作得很好。当我尝试映射我的自定义对象遗留物体

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库它就像一个魅力(它可能只是设置在遗留对象的值,没有必要建立新的LegacyEnum例如像ObjectMapper!),但我想解决这个问题,而不添加新的依赖。

有任何想法吗?

java enums legacy objectmapper
1个回答
0
投票

我使用的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 Spring配置注册的mixin:

@Configuration
public class ObjectMapperConfig {

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

这样,我可以使用LegacyClass如在控制器方法的参数。感谢您的线索。

© www.soinside.com 2019 - 2024. All rights reserved.