如何使用MapStruct映射kotlin.time.Duration与kotlinx.datetime.Instant?
data class Foo( val bar: String, // val baz: kotlin.time.Duration, // val baz2: kotlinx.datetime.Instant, val baz3: kotlinx.datetime.LocalDateTime ) data class FooDto( val bar: String, //val baz: kotlin.time.Duration, // val baz2: kotlinx.datetime.Instant, val baz3: kotlinx.datetime.LocalDateTime ) @Mapper(componentModel = MappingConstants.ComponentModel.SPRING) interface FooMapper { fun toDto(foo: Foo): FooDto }
当前该映射器可正常处理kotlinx.datetime.LocalDateTime类型属性,但处理kotlin.time.Duration和kotlinx.datetime.Instant类型属性时失败,报错信息如下:
FooDto does not have an accessible constructor.
kotlin.time.Duration和kotlinx.datetime.Instant确实未提供公共构造方法。如何让MapStruct支持这两种类型的映射?仅需实现Instant -> Instant和Duration -> Duration的映射。
解决方法
MapStruct默认会尝试通过构造方法实例化目标类型,而Duration和Instant没有公共构造方法,且我们只需要同类型直接映射,可通过以下两种方式处理:
方式1:引入自定义转换器类
创建包含静态转换方法的工具类,明确告诉MapStruct如何处理这两种类型的映射:
object DateTimeConverters { fun mapDuration(source: kotlin.time.Duration): kotlin.time.Duration = source fun mapInstant(source: kotlinx.datetime.Instant): kotlinx.datetime.Instant = source }
在Mapper接口中通过uses属性引入该类:
@Mapper( componentModel = MappingConstants.ComponentModel.SPRING, uses = [DateTimeConverters::class] ) interface FooMapper { fun toDto(foo: Foo): FooDto }
方式2:在Mapper中直接声明映射方法
无需额外工具类,直接在FooMapper内添加同类型映射方法,MapStruct会自动识别并使用:
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) interface FooMapper { fun toDto(foo: Foo): FooDto fun mapDuration(source: kotlin.time.Duration): kotlin.time.Duration = source fun mapInstant(source: kotlinx.datetime.Instant): kotlinx.datetime.Instant = source }
两种方式核心都是让MapStruct跳过构造方法实例化逻辑,直接复用原对象完成映射。
内容的提问来源于stack exchange,提问作者MatterOfFact
相关产品推荐
相关产品推荐

