mapstruct自定义转换,怎样将String转化为List

源码:https://gitee.com/cao_wen_bin/test

最近在公司遇到了这样一个为题,前端传过来的是一个List<Manager>,往数据库中保存到时候是String,这个String使用谷歌的json转化器。

当查询的时候在将这个数据库中String的数据以List<Manager>的形式返回给前端。

使用mapstruct中在怎样将String转化为List。在此记录一下。

1.引入依赖

xml 复制代码
<!--mapstruct-->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.5.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.5.5.Final</version>
</dependency>

2.PO->DTO

java 复制代码
package com.cao.pojo;

import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
@ToString
public class Manager {
    private String name;
    private String code;
}

需求是将PO转化为DTO,但是PO中的类型是String,而DTO中的类型是List

ManagerPO中的acctManagerList属性是String

java 复制代码
package com.cao.po;

import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
@ToString
public class ManagerPO {
    private Long id;
    private String acctManagerListString;
}

ManagerDTO中的acctManagerList属性是List<Manager>

java 复制代码
package com.cao.dto;

import com.cao.pojo.Manager;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.util.List;
@Data
@Accessors(chain = true)
@ToString
public class ManagerDTO {
    private Long id;
    private List<Manager> acctManagerList;
}

3.编写转换代码

因为我是使用的Gson把List<Manager>转换为String,所以从String转换为List<Manager>也要用相同的json转换,不然会出现异常

java 复制代码
import com.cao.dto.ManagerDTO;
import com.cao.po.ManagerPO;
import com.cao.pojo.Manager;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import java.util.List;

@Mapper
public interface ManagerBeanConvert {
    ManagerBeanConvert INSTANCE = Mappers.getMapper(ManagerBeanConvert.class);

    @Mapping(target = "id", source = "id")
    @Mapping(target = "acctManagerList", expression = "java(MapStruct.strToList(managerPO.getAcctManagerListString()))")
    ManagerDTO po2Dto(ManagerPO managerPO);

    @Mapping(target = "id", source = "id")
    @Mapping(target = "acctManagerListString", expression = "java(MapStruct.listToStr(managerDTO.getAcctManagerList()))")
    ManagerPO dto2Po(ManagerDTO managerDTO);

    class MapStruct {
        /**
         * po中的String转为dto中的list
         */
        public static List<Manager> strToList(String acctManagerListString) {
            if (StringUtils.isNotEmpty(acctManagerListString)) {
                // 将po中的acctManagerListString用Gson转换成为list(必须和list转String使用相同的转换器)
                List<Manager> managerList = new Gson().fromJson(acctManagerListString, new TypeToken<List<Manager>>() {}.getType());
                return managerList;
            }
            return null;
        }

	    /**
	     * dto中的list转为po中的String
	     */
	    public static String listToStr(List<Manager> managerList) {
	        if (!CollectionUtils.isEmpty(managerList)) {
	            // 将dto中的acctManagerList用Gson转换成为String(必须和String转list使用相同的转换器)
	            String managerListString = new Gson().toJson(managerList);
	            return managerListString;
	        }
	        return null;
	    }
    }
}

4.测试代码和测试

java 复制代码
import com.cao.beanconvert.ManagerBeanConvert;
import com.cao.dto.ManagerDTO;
import com.cao.po.ManagerPO;
import com.cao.pojo.Manager;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
@Slf4j
public class BeanConvertTest {
    public static void main(String[] args) {
        // po中的String转为dto中的list
        poString2DtoList();

        System.out.println("=====================");

        // dto中的list转为po中的String
        dtoList2PoString();
    }

    private static void dtoList2PoString() {
        List<Manager> managerList = new ArrayList<>();
        managerList.add(new Manager().setCode("0001").setName("管理员1号"));
        managerList.add(new Manager().setCode("0002").setName("管理员2号"));
        ManagerDTO managerDTO = new ManagerDTO().setId(3L).setAcctManagerList(managerList);
        log.info("managerDTO是: {}",managerDTO);
        ManagerPO managerPO = ManagerBeanConvert.INSTANCE.dto2Po(managerDTO);
        log.info("managerDTO转换为managerPO结果是: {}",managerPO);
    }

    private static void poString2DtoList() {
        //设置List<Manager>
        List<Manager> managerList = new ArrayList<>();
        managerList.add(new Manager().setCode("0001").setName("管理员1号"));
        managerList.add(new Manager().setCode("0002").setName("管理员2号"));
        //使用Gson将list转换成String
        String managerListString = new Gson().toJson(managerList);
        ManagerPO managerPO = new ManagerPO();
        managerPO.setId(1L).setAcctManagerListString(managerListString);
        log.info("managerPO是:{}",managerPO);
        ManagerDTO managerDTO = ManagerBeanConvert.INSTANCE.po2Dto(managerPO);
        log.info("managerPO转换为managerDTO结果是: {}",managerDTO);
    }
}

5.改造

虽然上面的写法已经可以满足需求了,但是在ManagerBeanConvert接口中写内部类的话不规范,所以要修改。

新建一个专门的用于类型属性的转换的类AttributeConvertUtil,将接口中的内部类挪到这个新建的类中,并在方法上面加上@Named("别名")

java 复制代码
import com.cao.pojo.Manager;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Named;
import org.springframework.util.CollectionUtils;

import java.util.List;

public class AttributeConvertUtil {
    /**
     * po中的String转为dto中的list
     */
    @Named("strToList")
    public List<Manager> strToList(String acctManagerListString) {
        if (StringUtils.isNotEmpty(acctManagerListString)) {
            // 将po中的acctManagerListString用Gson转换成为list(必须和list转String使用相同的转换器)
            List<Manager> managerList = new Gson().fromJson(acctManagerListString, new TypeToken<List<Manager>>() {
            }.getType());
            return managerList;
        }
        return null;
    }

    /**
     * dto中的list转为po中的String
     */
    @Named("listToStr")
    public String listToStr(List<Manager> managerList) {
        if (!CollectionUtils.isEmpty(managerList)) {
            // 将dto中的acctManagerList用Gson转换成为String(必须和String转list使用相同的转换器)
            String managerListString = new Gson().toJson(managerList);
            return managerListString;
        }
        return null;
    }
}

修改接口,

1.在@Mapper上引用我们的自定义转换代码类AttributeConvertUtil

2.使用qualifiedByName指定我们使用的自定义转换方法

java 复制代码
import com.cao.dto.ManagerDTO;
import com.cao.po.ManagerPO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper(uses = AttributeConvertUtil.class) //将自定义类引入进来
public interface ManagerBeanConvert {
    ManagerBeanConvert INSTANCE = Mappers.getMapper(ManagerBeanConvert.class);

    @Mapping(target = "id", source = "id")
    @Mapping(target = "acctManagerList", source = "acctManagerListString", qualifiedByName = "strToList")// qualifiedByName的值和别名一样
    ManagerDTO po2Dto(ManagerPO managerPO);

    @Mapping(target = "id", source = "id")
    @Mapping(target = "acctManagerListString", source = "acctManagerList", qualifiedByName = "listToStr") // qualifiedByName的值和别名一样
    ManagerPO dto2Po(ManagerDTO managerDTO);
}

源码:https://gitee.com/cao_wen_bin/test

相关推荐
我才是银古8 小时前
构建 Java GIS 工具库:从碎片化 API 到统一抽象的设计实践
java·gis·geotools·gdal·esri
敲代码的嘎仔9 小时前
实习日志day6--实习日志day6--title命名规范化&businessType纠正&补充缺失的@Log注解&报警与通信模块补充&产出阶段总结文档
java·开发语言·人工智能·git·python·实习·大二
编程(变成)小辣鸡9 小时前
Spring事务失效场景
java·后端·spring
极客先躯10 小时前
高级java每日一道面试题-2026年03月30日-实战篇[Docker]-如何监控容器的网络流量?
java·运维·docker·容器·prometheus·高级面试
tachibana210 小时前
hot100 翻转二叉树(226)
java·数据结构·算法·leetcode
brave_zhao10 小时前
nginx的进程架构
java·学习·nginx
兰令水10 小时前
leecodecode【面试150】【2026.7.9打卡-java版本】
java·数据结构·leetcode·面试·职场和发展
禾高网络10 小时前
互联网医院|AI 互联网医院成品开发系统
java·大数据·人工智能·小程序
shepherd11110 小时前
一次把 Spring MVC 文件上传参数“查没了”的排查:multipart、Filter 与 request body 的连环坑
java·spring boot·后端
lbb 小魔仙11 小时前
MuMu 模拟器 6.0 硬核测评:这次升级确实不一样
java·开发语言·模拟器·mumu·硬核测评