Mapstruct :在 @Mapping 的源参数中使用上下文

Fil*_*lip 15 mapstruct

在 @Mapper 中使用多个参数时,@Context 参数似乎无法访问

public interface MyMapper {  
      @Mapping(target="target1", source="arg1.arg") //works
      @Mapping(target="target2", source="arg2") //works
      @Mapping(target="target3", source="arg2.arg") //works
      @Mapping(target="target2", source="context.arg") //NOT WORKING
      public MyTarget convert(Object arg1, Object arg2, @Context Object context);
      
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用并expression=""解决它,但我无法让它工作。

有什么建议么?

我看得出来我不是唯一一个有此愿望的人。 https://github.com/mapstruct/mapstruct/issues/1280

谢谢

小智 26

我遇到了同样的场景,因为我需要一个@Context参数才能传递给嵌套映射函数,但也想将其用作@Mapping. 我能够使用expression以下方法实现这一目标:

public interface MyMapper {

  @Mapping(target="target1", source="arg1")
  @Mapping(target="target2", source="arg2")
  @Mapping(target="target3", expression="java( contextArg )")
  public MyTarget convert(Object arg1, Object arg2, @Context Object contextArg);

}
Run Code Online (Sandbox Code Playgroud)


Sja*_*aak 8

回答你的第二个问题:


public interface MyMapper {

  @Mapping(target="target1", source="arg1.arg")
  @Mapping(target="target2", ignore = true ) // leave to after mapping 
  MyTarget convert(Object arg1, @Context Object context);

  @AfterMapping
  default void convert(Object arg1, @MappingTarget MyTarget target, @Context context) {
        target.setTarget2( convert (context) );
  } 

  // if you have multipe mappings, you could address them here
  @Mapping(target="target2", source="context.arg") 
  MyInnerTarget convert(Object arg1, Object context);
}

Run Code Online (Sandbox Code Playgroud)


Sja*_*aak 5

根据定义,@Context带注释的对象不是源。它是上下文所以你不能像source@Mapping(target="target2", source="context.arg")

这是一个相关的github问题和官方答案:github问题

  • 删除“@Context”,MapStruct 会将其视为源对象。通过将其标记为“@Context”,您实际上告诉 MapStruct 忽略映射参数,但将其传递到底层方法调用中。此外,虽然 MapStruct 可以处理多个源参数,但它无法调用多个源参数方法来处理嵌套映射。API 将变得不可预测,并且选择机制将变得难以操作。 (4认同)
  • context == 根据定义 context.. 不是源参数.. 它的唯一目的是被映射忽略 (2认同)