【问题标题】:How to convert enum to POJO using mapstruct?如何使用 mapstruct 将枚举转换为 POJO?
【发布时间】:2017-04-21 08:08:12
【问题描述】:

如何在没有自定义实现的情况下使用 mapstruct 将枚举转换为 POJO?

例如

enum Type {
  T1, T2;

  private String description;

  private Type(String description) {
      this.description = description;
  }

  public String getDescription() { return this.description; }
}

像 POJO 一样

class TypeDto {
   private Type code;
   private String description;
}

仅供参考, 我使用 MapStruct 1.1.0.Final。

【问题讨论】:

  • 为什么你的 DTO 上有一个Type 字段?你不是要消除那个物体吗?
  • 我可以用String代替Type,不过我觉得没什么大不了的。

标签: java enums mapstruct


【解决方案1】:

您不能直接从枚举转换为对象。

您需要创建一个TypeMapper 和一个实现来处理转换。

类型转换

public class TypeConversion {
    public static void main(String[] args) {
        TypeDto t1 = TypeMapper.INSTANCE.typeToTypeDto(Type.T1);
        TypeDto t2 = TypeMapper.INSTANCE.typeToTypeDto(Type.T2);

        System.out.println(t1);
        System.out.println(t2);
    }
}

类型

public enum Type {
    T1("T-One"),
    T2("T-Two");

    private final String description;

    private Type(String description) {
        this.description = description;
    }

    public String getDescription() {
        return this.description;
    }
}

TypeDto

public class TypeDto {
    private String description;

    public TypeDto() {
        this("");
    }

    public TypeDto(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return String.format("TypeDto { \"description\": \"%s\" }", description);
    }
}

类型映射器

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface TypeMapper {
    TypeMapper INSTANCE = Mappers.getMapper(TypeMapper.class);

    @Mapping(source = "description", target = "description")
    TypeDto typeToTypeDto(Type type);
 }

TypeMapperImpl

public class TypeMapperImpl implements TypeMapper {
    @Override
    public TypeDto typeToTypeDto(Type type) {
        if (type == null) {
            return null;
        }

        return new TypeDto(type.getDescription());
    }
}

您可以通过创建通用映射器使此映射器可重用。

枚举映射器

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface EnumMapper<T, U extends Enum<?>> {
    @Mapping(target = "description")
    T enumToObject(U type);
 }

EnumMapperImpl

public abstract class EnumMapperImpl<T, U extends Enum<?>> implements EnumMapper<T, U> {
    @Override
    public T enumToObject(U type) {
        if (type == null) {
            return null;
        }

        return convert(type);
    }

    protected abstract T convert(U type);
}

然后你可以在你的 TypeMapper 中使用它。

类型映射器

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper
public interface TypeMapper extends EnumMapper<TypeDto, Type> {
    TypeMapper INSTANCE = Mappers.getMapper(TypeMapper.class);
}

TypeMapperImpl

public class TypeMapperImpl extends EnumMapperImpl<TypeDto, Type> implements TypeMapper {
    @Override
    protected TypeDto convert(Type type) {
        return new TypeDto(type.getDescription());
    }   
}

【讨论】:

  • *Impl都是mapstruct自动创建的吗?
  • 我相信是的。我认为它会在类路径中找到实现它的任何东西。
  • 我认为 TypeMapper 不适用于 1.1.0.Final mapstruct。我会检查的。
  • @AndreyBeletsky 我用最新版本对此进行了测试。我没有尝试更早的版本。
  • @AndreyBeletsky 查看以下项目并尝试构建它。单元测试应该成功。 GitHub: MappingExample.
【解决方案2】:

这不是 MapStruct 可以自动为您处理的。只需手动实现映射。 MapStruct 并非旨在为您处理每一个映射案例,而是将常见的 80% 自动化,让您自己处理更奇特的案例。

【讨论】:

    【解决方案3】:

    我现在用这个

    default TypeDto typeToTypeDto(Type type) {
        return new TypeDto(type.name(), type.getName());
    }
    

    由于缺乏其他解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 2016-03-20
      • 2010-09-06
      • 1970-01-01
      相关资源
      最近更新 更多