簡體   English   中英

如何使用 MapStruct 將 String 轉換為 Map?

[英]How can I convert String to Map using MapStruct?

我的 Spring Boot 應用程序中有Story實體。 它有String字段storyInfo ,其中包含:

{"title":"random title", "description":"random description"}

對於我的Story實體,我有StoryDTO和名為storyInfo map字段。 現在的問題是:我如何轉換String字段從StroryMapStoryDTO使用MapStruct

謝謝大家的回答。 通過向 MapStruct 的StoryMapper界面添加一些手動映射器,為我找到了最簡單的解決方案。

// Manual convert to Map
default Map toMap(String text){
    Map map = new HashMap();
    try {
        map = new ObjectMapper().readValue(text, new TypeReference<Map<String, String>>(){});
    } catch (IOException e) {
        e.printStackTrace();
    }

    return map;
}

// Manual convery from map
default String fromMap(Map map){
    return new JSONObject(map).toString();
}

嘗試以下代碼,靈感來自這里

@Mapper(componentModel = "spring")
public interface StoryMapper {

      @Mappings({
        @Mapping(source = "storyInfo", target = "storyInfo", qualifiedByName = "fromJsonToMap")
      })
      StoryDTO toStoryDTO(Story story);

      @Mappings({
        @Mapping(source = "storyInfo", target = "storyInfo", qualifiedByName = "fromMapToJson")
      })
      Story toStory(StoryDTO storyDTO);

      @Named("fromJsonToMap")
      default Map<String, Object> fromJsonToMap(String storyInfo) throws IOException {
        if (Objects.nonNull(storyInfo)) {
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Double> result = objectMapper.readValue(storyInfo, new TypeReference<Map<String, Object>>() {});
            return result;
        }
        return null;
      }

      @Named("fromMapToJson")
      default String fromMapToJson(Map<String, Object> storyInfo) throws JsonProcessingException {
        if (Objects.nonNull(storyInfo)) {
            ObjectMapper objectMapper = new ObjectMapper();
            String result = objectMapper.writeValueAsString(storyInfo);
            return result;
        }
        return null;
      }

}

已經提供的答案很好地解釋了如何提供服務來與 Jackson 進行映射。

為了使用 MapStruct 進行這項工作,您可以使用限定符並相應地注釋您的服務。

例如

@Qualifier // from the MapStruct package
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface FromJson {
}

public interface StringToMapConverter {

    @FromJson
    Map<String, String> convert(String string);
}

@Mapper(componentModel = "spring")
public interface MyMapper {

    @Mapping(target = "storyInfo", qualifiedBy = FromJson.class)
    StoryDTO convert(Story story);
}

StringToMapConverter的實現應該與已經提供的答案一樣。 您不必為轉換器使用專用接口,您還可以使用抽象映射器,注入ObjectMapper並執行其余操作。

然后 MapStruct 將使用它來將storyInfo String轉換為地圖。

一些其他可能的解決方案,超出了問題的范圍,如果您使用 Hibernate。 您可以在實體中使用Map<String, String> ,但仍將其映射到數據庫中的 String 。 看看 Vlad Mihalcea 的hibernate-types ,它允許使用額外的類型,以便您可以將對象作為 JSON 保存在數據庫中

  1. 您可以創建一個通用工具類,以便其他 Mapper 也可以使用。

    ps:JsonUtil 只是一個 util clss 用於將 Object 轉換為 Json。

    您可以使用 jackson、fastjson、gson。

@Component
public class MapStructUtil {

    @Qualifier
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface JsonStrToMap {

    }

    @Qualifier
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface MapToJsonStr {

    }

    @JsonStrToMap
    public Map jsonStrToMap(String jsonStr) {
        return JsonUtil.toMap(jsonStr);
    }

    @MapToJsonStr
    public String mapToJsonStr(Map<String, String> map) {
        return JsonUtil.toJsonString(map);
    }
}
  1. 然后你可以像這樣在你的 Mapper 中使用它

ps:這里使用componentModel = "spring",所以需要在MapStructUtil中添加@Componnent注解

@Mapper(componentModel = "spring", uses = {MapStructUtil.class})
public interface StoryMapper {

      @Mapping(source = "storyInfo", target = "storyInfo", qualifiedBy = JsonStrToMap.class)
      StoryDTO toStoryDTO(Story story);

      @Mapping(source = "storyInfo", target = "storyInfo", qualifiedBy = MapToJsonStr.class)
      Story toStory(StoryDTO storyDTO);

}

我不熟悉MapStruct ,但我可能會建議一個替代方案,因為您是在 Spring 上下文中運行您的應用程序。

由於您的字符串是 JSON 字符串,因此您最好的做法是使用 JSON 庫。 Spring Boot 帶有自己的 Jackson ObjectMapper預配置實例(您可以通過在任何@Configuration類中定義使用ObjectMapper類型的@Bean來覆蓋以添加/刪除特定功能)。

您可以使用以下方法注入一個實例:

@Autowired
ObjectMapper objectMapper;

之后,您可以使用對象映射器將字符串轉換為HashMap<String, String> (或您需要的任何類型),如下所示:

Map<String, String> result = objectMapper.readValue(storyInfo, new TypeReference<Map<String, String>>() {});

我將嘗試使用MapStruct方法更新此答案,但此時這可能對您更實用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM