如何解决将Jackson与不可变的类一起使用Private Builder
我正在尝试使用Jackson来对DynamoDB V2 AttributeValue类进行序列化/反序列化。
使用构建器将其设置为不可变的类,并且该构建器具有私有构造函数。为了创建一个构建器,您需要调用AttributeValue.builder()
。
我对此课程没有控制权,所以我想使用Jackson混音。
我用过@JsonDeserialize(builder = AttributeValue.Builder::class)
并注册了mixin:
@JsonDeserialize(builder = AttributeValue.Builder::class)
interface AttributeValueMixin {
}
private val mapper = jacksonObjectMapper()
.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY)
.addMixIn(AttributeValue::class.java,AttributeValueMixin::class.java)
但是,杰克逊(Jackson)尝试使用AttributeValue.Builder
的默认构造函数,但是它没有,所以不能使用。
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造
software.amazon.awssdk.services.dynamodb.model.AttributeValue$Builder
的实例(不存在像默认构造一样的创建者)
我如何让Jackson使用AttributeValue.builder()
工厂功能?或关于如何使用Jackson来对这个AttributeValue
类进行序列化/反序列化的其他想法?
解决方法
确实很棘手。我可以想到两种解决方案:
- 围绕原始构建器创建包装器:
class BuilderDelegate {
var field1 : String? = null
var field2 : String? = null
...
fun build() = AttributeValue.builder().also {
it.field1 = field1
it.field2 = field2
...
}.build()
}
@JsonDeserialize(builder = BuilderDelegate::class)
interface AttributeValueMixin {
}
- 如果您直接调用对象映射器,则可以尝试以下方法:
val builder = mapper.readerForUpdating(AttributeValue.builder())
val value = builder.readValue<AttributeValue.Builder>(jsonData).build()
,
请参阅我的回答这个问题:https://stackoverflow.com/a/65603336/2288986
总结
首先是一个辅助方法:
static ValueInstantiator createDefaultValueInstantiator(DeserializationConfig config,JavaType valueType,Supplier<?> creator) {
class Instantiator extends StdValueInstantiator {
public Instantiator(DeserializationConfig config,JavaType valueType) {
super(config,valueType);
}
@Override
public boolean canCreateUsingDefault() {
return true;
}
@Override
public Object createUsingDefault(DeserializationContext ctxt) {
return creator.get();
}
}
return new Instantiator(config,valueType);
}
然后添加ValueInstantiator
为你的类:
var mapper = new ObjectMapper();
var module = new SimpleModule()
.addValueInstantiator(
AttributeValue.Builder.class,createDefaultValueInstantiator(
mapper.getDeserializationConfig(),mapper.getTypeFactory().constructType(AttributeValue.Builder.class),AttributeValue::builder
)
);
mapper.registerModule(module);
现在杰克逊将能够实例化一个AttributeValue.Builder
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。