MapStruct 映射non-related 相似类

MapStruct map non-related similar classes

我有一堆 same-named classes 在各种包中具有相同的属性。假设每个 class 看起来像这样:

public class MiddlewareHeaderType {

    private String longPrefixRequestId;
    private String abcReason;
    private String defSubject;
}
com.mycompany.generated.ws.serviceA.MiddlewareHeader;
com.mycompany.generated.ws.serviceB.MiddlewareHeader;
com.mycompany.generated.ws.serviceC.MiddlewareHeader;
...

只要生成它们,我就无法更改它们(假设来自 XSD)。我想要一个通用的 object,比如 MySoapHeader 用作源数据,使用 MapStruct 和 Java 11(我我不仅限于 Java 8 个功能)。

public class MySoapHeader {

    private String requestId;
    private String reason;
    private String subject;
}

我不愿意为每个生成的 header object 创建一个单独的映射器 class,只要它们有数百个。但它们几乎是一样的。

我的尝试不适用于通用值,而且我在任何地方都找不到处理类似问题的答案:

@Named("base")
@Mapping(target = "longPrefixRequestId", source = "requestId")
@Mapping(target = "abcReason", source = "reason")
@Mapping(target = "defSubject", source = "subject")
<T> T base(MySoapHeader mySoapHeader);

@Mapping(target = "MiddlewareHeaderType", qualifiedByName = "base")
com.mycompany.generated.ws.serviceA.MiddlewareHeaderType serviceAHeader(MySoapHeader mySoapHeader);

@Mapping(target = "MiddlewareHeaderType", qualifiedByName = "base")
com.mycompany.generated.ws.serviceB.MiddlewareHeaderType serviceBHeader(MySoapHeader mySoapHeader);

@Mapping(target = "MiddlewareHeaderType", qualifiedByName = "base")
com.mycompany.generated.ws.serviceC.MiddlewareHeaderType serviceCHeader(MySoapHeader mySoapHeader);

乍一看,您似乎颠倒了 targetsource 属性。 MySoapHeader.class 中有 requestId,这是基本方法的来源。

您正在寻找的是类似映射合成的东西。我们在 1.4 中添加了此支持(现在仍处于 Beta 阶段)。

有了它,您可以定义自己的自定义映射注释。

例如

@Retention(RetentionPolicy.CLASS)
@Mapping(target = "longPrefixRequestId", source = "requestId")
@Mapping(target = "abcReason", source = "reason")
@Mapping(target = "defSubject", source = "subject")
public @interface SoapHeaderMapping { }

然后在您的映射器中,您可以执行以下操作:

@Mapper
public interface HeaderMapper {

    @SoapHeaderMapping
    com.mycompany.generated.ws.serviceA.MiddlewareHeaderType serviceAHeader(MySoapHeader mySoapHeader);

    @SoapHeaderMapping
    com.mycompany.generated.ws.serviceB.MiddlewareHeaderType serviceBHeader(MySoapHeader mySoapHeader);

    @SoapHeaderMapping
    com.mycompany.generated.ws.serviceC.MiddlewareHeaderType serviceCHeader(MySoapHeader mySoapHeader);

}

可以找到更多信息here