背景
调用公司影像识别服务接口,返回值都是 Map<String,Object>类型,有的key很多。想把这种 map 结果转为项目中对应的JavaBean如DTO 或者 VO,又不想写很多的 dto.setXxx(map.get(“xxx”)) 的代码。(注:可以使用fastjson等工具序列化Map,再反序列化为DTO类;本文只关注 MapStruct)
结果
查阅测试了一下,MapStruct 目前(
1.3.1.Final 及之前
)的版本暂不支持直接将 map 转换成 JavaBean,很早之前有人在 GitHub提了这个
feature(Please add a feature to map from java.util.map to an object #1075),
MapStruct 在
1.5.0.Beta1
版本开始提供这项功能,
https://mapstruct.org/news/2021-07-18-mapstruct-1_5_0_Beta1-is-out/
1.5.0.Beta1 起始版本:
官网示例:
1.5.0.Beta1 之前版本:
当然目前版本也可以通过 MapStruct 的一些特性来间接实现 map 转换为 JavaBean,其中一种方式是使用 @Mapping注解中的
expression
表达式指定 map 中的 key 和 JavaBean 字段的映射关系,如下例 map 转换为 Person 对象:
Person
:
public class Person {
private String name;
private String hobby;
private String school;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
@Override
public String toString(){
return new StringBuilder().append("{").append("name:").append(name).append(",hobby:")
.append(hobby).append(",school:").append(school).append("}").toString();
}
}
Converter:
@Mapper
public interface Converter {
Converter INSTANCE = Mappers.getMapper(Converter.class);
@Mappings({@Mapping(expression = "java(map.get(\"name\"))", target = "name"),
@Mapping(expression = "java(map.get(\"hobby\"))", target = "hobby"),
@Mapping(expression = "java(map.get(\"school\"))", target = "school")})
Person mapPerson(Map<String, String> map);
}
Test 类
:
public class Test {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String, String>();
map.put("name", "小明");
map.put("hobby", "足球");
map.put("school", "育英小学");
Person person = Converter.INSTANCE.mapPerson(map);
System.out.println(person);
}
}
输出结果:
{name:小明,hobby:足球,school:育英小学}
这种方式虽然可行,但是感觉不理想,还是写了很多 map.get(“xxx”), 只不过写到了 @Mapping 注解中了。(不过@Mapping 注解中的 expression 表达式很有意思)
还有一种利用自定义注解的方式,但是感觉太繁琐了,而且很难阅读,更不推荐了,可以参考下面的参考文档。
参考文档
:
MapStruct 1.5.0.Beta2 Reference Guide
MapStruct: mapping from java.util.Map to Bean? – Stack Overflow
java – Mapstruct: HashMap as source to Object – Stack Overflow