我在与建设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!),但我想解决这个问题,而不添加新的依赖。
有任何想法吗?
我使用的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如在控制器方法的参数。感谢您的线索。