我的Spring Boot应用程序中有Story
实体。它有String
字段storyInfo
,其中包含:
{"title":"random title", "description":"random description"}
对于我的Story
实体,我有StoryDTO
与map
字段称为storyInfo
。问题是:如何使用String
将Strory
中的Map
场转换为StoryDTO
中的MapStruct
?
已经提供的answer很好地解释了如何提供服务来与杰克逊进行映射。
为了使这个功能与MapStruct一起使用,您可以使用qualifiers并相应地注释您的服务。
例如
@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>
,但仍将其映射到DB中的String。看看Vlad Mihalcea的hibernate-types,它允许使用额外的类型,因此您可以将对象作为JSON保存在数据库中
谢谢你们的回答。通过向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();
}
尝试以下代码,灵感来自here
@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;
}
}
我不熟悉MapStruct
,但我可能会建议一个替代方法,因为您在Spring上下文中运行应用程序。
由于您的字符串是JSON字符串,因此您最好的方法是使用JSON库。 Spring Boot附带了自己的预先配置的Jackson ObjectMapper
实例(您可以通过在任何@Bean
类中使用ObjectMapper
类型的@Configuration
来定义添加/删除特定功能)。
您可以使用以下方法注入此实例:
@Autowired
ObjectMapper objectMapper;
之后,您可以使用对象映射器将字符串转换为HashMap<String, String>
(或您需要的任何类型),如下所示:
Map<String, String> result = objectMapper.readValue(storyInfo, new TypeReference<Map<String, String>>() {});
我将尝试使用MapStruct
方法更新此答案,但也许这对您来说可能更实用。