MapStruct使用@Context传递上下文属性报错:No property named 'myContext1.param1' exists的解决咨询
MapStruct使用@Context传递上下文属性报错:No property named 'myContext1.param1' exists的解决咨询
嘿,我来帮你捋清楚这个问题的根源和解决办法~
首先,你遇到的报错原因很明确:MapStruct的@Context注解标记的参数,默认是作为映射上下文来使用的,不是用来直接当作映射源的属性容器。所以你直接在@Mapping的source里写myContext1.param1时,MapStruct只会去主源对象(也就是这里的MySource)里找属性,自然找不到myContext1.param1这个路径啦。
接下来给你两种可行的解决思路,你可以根据自己的场景选:
方案一:用@AfterMapping手动注入上下文属性
这种方式保留@Context的用法,先让MapStruct自动映射主源对象的属性,再通过@AfterMapping方法把上下文里的属性手动赋值给目标对象:
@Mapper interface MyMapper { // 先映射MySource里的name属性 @Mapping(target = "name", source = "name") fun mapMy( mySource: MySource, @Context myContext1: MyContext1, @Context myContext2: MyContext2 ): MyTarget // 用@AfterMapping在自动映射完成后,补充上下文属性 @AfterMapping fun setContextProperties( @MappingTarget target: MyTarget, @Context myContext1: MyContext1, @Context myContext2: MyContext2 ) { target.param1 = myContext1.param1 target.param2 = myContext2.param2 } }
方案二:去掉@Context,把上下文参数当作普通源参数
如果这些参数只是用来提供映射所需的属性,不需要利用@Context在嵌套映射中传递上下文的特性,那直接去掉@Context注解,让MapStruct把它们当作普通的源参数处理,此时需要在@Mapping里明确指定参数名.属性名:
@Mapper interface MyMapper { @Mapping(target = "name", source = "mySource.name") @Mapping(target = "param1", source = "myContext1.param1") @Mapping(target = "param2", source = "myContext2.param2") fun mapMy( mySource: MySource, myContext1: MyContext1, myContext2: MyContext2 ): MyTarget }
关于你提到的QualifiedByName示例的区别
你说的那个多参数QualifiedByName示例,@Context的用法是给自定义的转换方法传递额外参数,而不是直接在@Mapping的source里引用上下文属性。举个类似的例子:
@Mapper interface MyMapper { // 把MySource的name交给自定义方法转换,同时传递上下文参数 @Mapping(target = "param1", source = "name", qualifiedByName = "generateParam1") fun mapMy( mySource: MySource, @Context myContext1: MyContext1 ): MyTarget // 自定义方法接收源属性和上下文参数,生成目标属性值 @Named("generateParam1") fun generateParam1(sourceName: String, @Context context: MyContext1): String { return "${sourceName}_${context.param1}" } }
这里@Context是用来给@Named标记的自定义转换方法传参的,和你直接在@Mapping里引用上下文属性的用法完全不同,这就是两者的核心区别啦。
内容来源于stack exchange
相关产品推荐
相关产品推荐

