MapStruct Map 转换成对象

  • Post author:
  • Post category:其他


背景

调用公司影像识别服务接口,返回值都是 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



版权声明:本文为qq_22076345原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。