MapStruct:将目标字段类型用作对象时发生错误

MapStruct: error occur when using Target field type as Object

当我尝试让 MapStruct 将类型转换为 Object 时,效果不佳。

目标Class

public static class Filterable implements Name,Disassemble,Note{
    String name;
    String disassemble;
    Object note; // <-- Object type

    ... getter setter
}

映射摘要class

@Mappings({
        @Mapping(source = "s",target = "name"),
        @Mapping(source = "s",target = "note"), // <--
        @Mapping(source = "s",target = "disassemble", qualifiedByName = "toDisassemble")
})
public abstract UiDto.Option.Filterable toUiFilterableOption(String s);

编译时的结果

@Override
public Filterable toUiFilterableOption(String s) {
    if ( s == null ) {
        return null;
    }

    Filterable filterable = new Filterable();

    filterable.setName( s );
    filterable.setNote( toUiFilterableOption( s ) ); // <-- hear is problem
    filterable.setDisassemble( Converter.toDisassemble( s ) );

    return filterable;
}

我该如何解决这个问题?

MapStruct 尝试找到从源 class 映射到目标 class 的方法:Object map(String source).

只要目标class是Object,注解@Mapping的方法本身就有合适的方法签名:Filterable toUiFilterableOption(String s)。因为 Filterable 就像 Java 中的任何其他 class 一样是 Object。方法参数也是 String.

要解决此问题,请在 @Mapping 中使用 qualifiedByName 并添加一个用 @Named:

注释的映射方法
@Mapper
public abstract class TestMapper {

  public static final TestMapper TEST_MAPPER = Mappers.getMapper(TestMapper.class);

  @Mapping(source = "s", target = "name")
  @Mapping(source = "s", target = "note", qualifiedByName = "toNote")
  @Mapping(source = "s", target = "disassemble", qualifiedByName = "toDisassemble")
  public abstract Filterable toUiFilterableOption(String s);

  @Named("toNote")
  protected Object toNote(String s) {
    return s.toUpperCase(); //just as an example
  }

  //...
}

生成的代码如下所示:

public class TestMapperImpl extends TestMapper {

  @Override
  public Filterable toUiFilterableOption(String s) {
    if (s == null) {
      return null;
    }

    Filterable filterable = new Filterable();

    filterable.setName(s);
    filterable.setNote(toNote(s));
    filterable.setDisassemble(toDisassemble(s));

    return filterable;
  }
}