Mapstruct:对所有枚举使用相同的映射器

Mapstruct: Using same mapper for all enums

我试图将所有 enums 映射到同一个 DTO class,我想避免为每个 enum 类型声明一种方法,或使用 @Mapping对于每个枚举字段。

@Mapper
public interface EnumDtoMapper
{
    // approach one
    default <E extends Enum<E>> EnumDTO enumToEnumDTO(Enum<E> e)
    {
        if (e == null)
        {
            return null;
        }
        EnumDTO enumDTO = new EnumDTO();
        enumDTO.setName(e.name());
        return enumDTO;
    }

    //approach two: enum -> String -> EnumDTO
    default <E extends Enum<E>> String enumToString(Enum<E> e)
    {
        return e.name();
    }


    default EnumDTO stringToEumDTO(String name)
    {
        EnumDTO enumDTO = new EnumDTO();
        enumDTO.setName(name);
        return enumDTO;
    }
}

然后在我的其他 Mappers 上

@Mapper(componentModel = "cdi", injectionStrategy = InjectionStrategy.CONSTRUCTOR, uses = {
        EnumDtoMapper.class
})

但是 MapStruct 仍在为每个枚举类型生成新的映射方法,实现不符合我的需要。

有没有办法用 MapStruct 做到这一点?还是魔法太多了? :D

做了一些测试,没有将 componentModel 设置为 cdi 你所拥有的会产生你所期望的。 但是有了它,你需要通配输入的通用类型enum,之后它应该可以工作。

例子

如果 EnumUtil 看起来像这样:

class EnumUtil {

    static EnumDto enumToEnumDTO(Enum<?> e) {
        if ( e == null ) {
            return null;
        }
        EnumDto enumDTO = new EnumDto( e.name() );
        return enumDTO;
    }

    // approach two: enum -> String -> EnumDTO
    static String enumToString(Enum<?> e) {
        return e.name();
    }

    static EnumDto stringToEumDTO(String name) {
        return new EnumDto( name );
    }
}

使用以下映射器和 类:

@Mapper( componentModel = ComponentModel.CDI,
        injectionStrategy = InjectionStrategy.CONSTRUCTOR,
        uses = {
            EnumUtil.class
        } )
public interface EnumMapper {

    @Mapping( target = "value", source = "enumValue" )
    DtoWithEnumDto map(SourceWithEnum source);
}

class SourceWithEnum {
    private MyEnum enumValue;
    // getter & setter
}

enum MyEnum {
    SOMETHING, ELSE
}

class EnumDto {
    private final String name;
    // constructor and getter
}

class DtoWithEnumDto {
    private EnumDto value;
    // constructor, getter and setter
}

您将获得以下生成的映射器:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2022-02-21T16:59:06+0100",
    comments = "version: 1.4.2.Final, compiler: Eclipse JDT (IDE) 1.4.50.v20210914-1429, environment: Java 17.0.1 (Azul Systems, Inc.)"
)
@ApplicationScoped
public class EnumMapperImpl implements EnumMapper {

    @Override
    public DtoWithEnumDto map(SourceWithEnum source) {
        if ( source == null ) {
            return null;
        }

        EnumDto value = null;

        value = EnumUtil.enumToEnumDTO( source.getEnumValue() );

        DtoWithEnumDto dtoWithEnumDto = new DtoWithEnumDto( value );

        return dtoWithEnumDto;
    }
}