我正在学习如何在Spring Boot和Kotlin项目中使用Mapstruct。
我有一个生成的DTO(ThessaurusDTO),它有一个List,我需要在我的模型(Vocab)上把它映射成一个List。
MapStruct不能自动映射这一点是有道理的,但我知道事实上,第一个列表总是大小=1。我无法控制DTO模型所属的API。我发现在 文件 我可以在接口中创建定义一个默认的方法实现,这将大致翻译成Kotlin中的一个普通函数。
我的映射器界面。
@Mapper
interface VocabMapper {
@Mappings(
// ...
)
fun thessaurusToVocab(thessaurusDTO: ThessaurusDTO): Vocab
fun metaSyns(nestedList: List<List<String>>): List<String>
= nestedList.flatten()
}
当我试图进行构建时,我得到了以下错误。
VocabMapper.java:16: error: Can't map collection element "java.util.List<java.lang.String>" to "java.lang.String ". Consider to declare/implement a mapping method: "java.lang.String map(java.util.List<java.lang.String> value)".
看起来mapStruct仍在试图自动进行映射 而忽略了我的自定义实现。我是不是漏掉了什么小事?
我在文档中发现,我可以在接口中创建定义一个默认的方法实现,这将宽泛地翻译成Kotlin中的一个普通函数。
根据我在网上查到的了解,Kotlin并没有正确地将接口函数翻译成Java中的默认方法,而是实际生成了一个实现接口的类。
如果是这个问题的话,你可以在类中注释 metaSyns
与 @JvmDefault
:
指定应该为非抽象的 Kotlin 接口成员生成 JVM 默认方法。
使用该注解需要指定一个明确的编译参数:要么是
-Xjvm-default=enable
或-Xjvm-default=compatibility
.
请看链接中的区别,但你可能需要。-Xjvm-default=enable
.
我看到已经通过依靠基于抽象的实现来解决这个问题,而不是使用接口.根据我在网上找到的理解,Kotlin并没有正确地将接口函数翻译成Java中的默认方法,而是实际上生成了一个实现接口的类。