How can I map properties conditionally with MapStruct 1.2?

我们两清 提交于 2021-02-08 12:38:08

问题


Is it possible with MapStruct 1.2 to map a source property with a specific value to a specific different value in the target?

I think about something like this:

public abstract class JiraKpmMapper {
    @Mappings({
    @Mapping(source = "mySource.propA", target = "myTarget.propX")
    })
    @ValueMappings({
        @ValueMapping(source = "ABC", target = "XYZ"),
        @ValueMapping(source = "123", target = "789")
    })
    public abstract MyTarget source2Target(final MySource mySource);

}

So that when MapStruct sees during the mapping that when mySource.propA has the value "ABC" myTarget.propX needs to be set to value "XYZ" and so forth.

To be more precisely, I even want something more elaborated: The target should be a class haven three properties in which the resulting target value must be split into. For instance, if mySource.propA has the value "ABC" the target myTarget should get a value like "V01.123.456.AB". This value in turn shall be split up in a preValue, a middleValue and an endValue:

preValue = "V01"

middleValue = "123.456"

endValue = "AB"

whereby there's no property holding the complete result string.

That's why I already wrote a custom mapper and I tell the MyMapper to use it via

@Mapper(componentModel = "spring", uses = MyCustomMapper.class)

This works so far but I can't achieve it to tell the MyCustomMapper to put "V01.123.456.AB" into the target when the souzrce comes with "ABC".


回答1:


You can't really do that with MapStruct. The @ValueMapping annotation is for mapping of Enum(s).

In order to achieve what you are looking for you would need to do that in @BeforeMapping or @AfterMapping.

For example you can do something like:

@Mapper
public interface JiraKpmMapper {

    @BeforeMapping
    default void beforeMapping(@MappingTarget MyTarget target, MySource source) {
        if (source.getPropY().equals("ABC") {
            target.setPropX("V01.123.456.AB");
        }
    }

    @Mapping(target = "propX", ignore = true) // This is now mapped in beforeMapping
    MyTarget source2Target(final MySource mySource);
}

Your custom mapper then should have an @AfterMapping. Where you would convert the propX into your class. You can even do this as part of the @BeforeMapping I wrote and directly create your class (or invoke the method that does the conversion from String into a class)




回答2:


you can do something like this

@Mapping(target = "myTarget.propX",expression="java(mySource.getPropA().equals(\"Abc\")?"\"V01.123.456.AB\":\"\")")


来源:https://stackoverflow.com/questions/49067870/how-can-i-map-properties-conditionally-with-mapstruct-1-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!