使用 MapStruct 通过定位值进行枚举查找

问题描述

我已经实现了我的基本要求,它们在一个简单的场景中运行良好,如下面的代码片段所述。但是对于新要求,我需要帮助的最佳方法是什么。

新要求:数字格式的状态用于其他服务,但在请求-响应状态表示中是这些用户友好的字符串 ["Not Started","In Progress","Completed"]

@AllArgsConstructor
@Getter
public enum StatusEnum {
    NOT_STARTED(1,"Not Started"),IN_PROGRESS(2,"In Progress"),COMPLETED(3,"Completed");    
    private final int key;
    private final String value;
}    

下面是我的 MapStruct 逻辑,用于将枚举转换为字符串和反之亦然的转换逻辑。这适用于基本要求。但新需求的逻辑是什么?

ActionItem.java:

private Constants.StatusEnum status;

基本要求适用于以下实现:

@AllArgsConstructor
@Getter
public enum StatusEnum {
    NOT_STARTED("Not Started"),IN_PROGRESS("In Progress"),COMPLETED("Completed");
    private final String value;
}


@Mapper
public interface ActionItemmapper extents BaseMapper {
     @Mapping(source = "status",target = "status",qualifiedByName = "statusEnumToString")
     ActionItemResponse toActionItemResponse(ActionItem actionItem);
}

@Mapper
public interface BaseMapper {   
     @Named("statusEnumToString")
     default String statusEnumToString(Constants.StatusEnum statusEnum) {
        return statusEnum.getValue();
     }

     @Named("statusstringToEnum")
     default Constants.StatusEnum statusstringToEnum(String status) {
        return List.of(Constants.StatusEnum.values()).stream().filter(s -> s.getValue().equals(status)).findAny()
        .orElse(null);
     }
}

解决方法

我得到了解决方案。

@AllArgsConstructor
@Getter
public enum StatusEnum {
    NOT_STARTED(1,"Not Started"),IN_PROGRESS(2,"In Progress"),COMPLETED(3,"Completed");
    private final String key;        
    private final String value;
}


@Mapper
public interface ActionItemMapper extents BaseMapper {
     @Mapping(source = "status",target = "status",qualifiedByName = "statusEnumToString")
     ActionItemResponse toActionItemResponse(ActionItem actionItem);
}

@Mapper
public interface BaseMapper {   

   @Named("statusEnumKeyToValue")
   default String statusEnumKeyToValue(Integer status) {
       String value = null;
       for (Constants.StatusEnum statusEnum: Constants.StatusEnum.values()) {
           if (statusEnum.getKey().equals(status)) {
               value = statusEnum.getValue();
               break;
           }
       }
       if (value == null) {
           throw new IllegalArgumentException("No status value found for status key " +status);
       }
       return value;
   }

   @Named("statusEnumValueToKey")
   default Integer statusEnumValueToKey(String status) {
       return statusStringToEnum(status).getKey();
   }


   default Constants.StatusEnum statusStringToEnum(String status) {
      return List.of(Constants.StatusEnum.values()).stream().filter(s -> s.getValue().equals(status)).findAny()
        .orElseThrow()
   }
}