整改步骤。

1、凭借mapstruct关键词 ,搜寻几篇博客。

2、浏览博客,依赖,部分代码实践的示例。

3、脑袋感觉会了。动手。碰壁再说,之后再回来看原理。

实际代码整合。整起。

1、添加对应依赖架包。 先拿1.2.0.Final试手

<!-- 追加本次 mapstruct依赖 以下 -->
    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-jdk8</artifactId>
      <version>1.2.0.Final</version>
    </dependency>

    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-processor</artifactId>
      <version>1.2.0.Final</version>
    </dependency>
    <!-- 追加本次 mapstruct依赖 以上 -->

springboot 用map接收不到参数 springboot接受map_数据

2、整改实体类(实体类不变)

3、整改cover

springboot 用map接收不到参数 springboot接受map_java_02

整合代码如下

/**
* XXXModelConverterForTestSpring 取名意思很明显。本次搞事是以是为了测试。另外方式是用 Spring注入方式
* <br/>
* @author FUHUA
* @date 2021/8/21 8:58
*/
@Mapper(componentModel = "spring")
public interface  XXXModelConverterForTestSpring {

    XXXModelConverterForTestSpring INSTANCE = Mappers.getMapper(XXXModelConverterForTestSpring.class);

    /** 对应 mappings 对应数据关系。  source是源,也就是传入实体类的参数命名  target是目标 也就是我想转换过去的数据  */
    @Mappings({
        @Mapping(source = "YI", target = "YI"),
            @Mapping(  expression = "java(DateFormatUtils.getFullString(XXXDO.getER()))",target = "ER" ),
            @Mapping(expression = "java(EnumUtils.getEnum(StatusEnum.class, bidDO.getStatus()))", target = "status"),
            @Mapping(source = "memo", target = "memo"),
            @Mapping(source = "projectType", target = "projectType"),
    })
    XXXModel convertToModelForTest(XXXDO XXXDO);

    /**
     * Convert XXXDO to XXXModel
     *
     * @param XXXDO 
     */
    public static XXXModel convertToModel(XXXDO XXXDO) {
        if (bidDO == null) {
            return null;
        }
        XXXModel XXXModel = new XXXModel();

        XXXModel.setYI(XXXDO.getYI());
      
        XXXModel.setXXXER(DateFormatUtils.getFullString(XXXDO.getER()));
        XXXModel.setStatus(EnumUtils.getEnum(StatusEnum.class, XXXDO.getStatus()));
        XXXModel.setMemo(XXXDO.getMemo());
        XXXModel.setProjectType(XXXDO.getProjectType());

        return XXXModel;
    }
}

4、编译搞事。看看效果

出现问题。

springboot 用map接收不到参数 springboot接受map_实体类_03

springboot 用map接收不到参数 springboot接受map_java_04

本地的话。直接选中某个但是还是可能会导致,其余未正常编译。本次硬要编译启动,暂时移除这部分存在冲突的部分。

去掉上面时间跟枚举类转换。仅留下get跟set部分基础操作。

同名不同包。会在自动编译环节卡住。这个用不了。

springboot 用map接收不到参数 springboot接受map_数据_05

5、简单转换应该是成功的。似乎不存在网上说的 maven 跟lombok 版本问题。 不过后面还是难说。

6、对应部分同名方法可能存在多个不同的架包内,导致系统自动引用无法确定引用到具体的,所以采用全路径写法实现

/**
* xxxModelConverterForTestSpring 取名意思很明显。本次搞事是以是为了测试。另外方式是用 Spring注入方式
* <br/>
* @author fuhua
* @date 2021/8/21 8:58
*/
@Mapper(componentModel = "spring")
    public interface  XXXModelConverterForTestSpring {

    XXXModelConverterForTestSpring INSTANCE = Mappers.getMapper(XXXModelConverterForTestSpring.class);

    /** 对应 mappings 对应数据关系。  source是源,也就是传入实体类的参数命名  target是目标 也就是我想转换过去的数据  */
    @Mappings({
        @Mapping(source = "policyNo", target = "policyNo"),
            @Mapping(source = "deadline", target = "bidDeadline"),
            @Mapping(  expression = "java(com.XXXX.framework.core.util.DateFormatUtils.getFullString(XXXDO.getStartTime()))",target = "XXXStartTime" ),
            @Mapping(expression = "java(com.XXXX.framework.core.util.DateFormatUtils.getFullString(XXXDO.getEndTime()))",target = "bidEndTime"),
            @Mapping(expression = "java(com.XXXX.framework.core.util.DateFormatUtils.getFullString(XXXDO.getOpenTime()))",target = "bidOpenTime"),
            @Mapping(source = "fileNo", target = "bidFileNo"),
            @Mapping(source = "projectName", target = "projectName"),
            @Mapping(source = "businessId", target = "businessId"),
            @Mapping(source = "estimatedAmount", target = "estimatedAmount"),
            @Mapping(expression = "java(com.XXXX.framework.core.util.EnumUtils.getEnum(com.XXXX.framework.core.enums.StatusEnum.class, XXXDO.getStatus()))", target = "status"),
            @Mapping(source = "memo", target = "memo"),
            @Mapping(source = "projectType", target = "projectType"),
    })
    XXXModel convertToModelForTest(XXXDO XXXDO);

    /**
     * Convert XXXDO to XXXModel
     *
     * @param XXXDO 标的实体
     */
    public static XXXModel convertToModel(XXXDO XXXDO) {
        if (XXXDO == null) {
            return null;
        }
        XXXModel XXXModel = new XXXModel();

        XXXModel.setPolicyNo(XXXDO.getPolicyNo());
        XXXModel.setBidDeadline(XXXDO.getDeadline());
        XXXModel.setBidStartTime(DateFormatUtils.getFullString(XXXDO.getStartTime()));
        XXXModel.setBidEndTime(DateFormatUtils.getFullString(XXXDO.getEndTime()));
        XXXModel.setBidOpenTime(DateFormatUtils.getFullString(XXXDO.getOpenTime()));
        XXXModel.setBidFileNo(XXXDO.getFileNo());
        XXXModel.setProjectName(XXXDO.getProjectName());
        XXXModel.setBusinessId(XXXDO.getBusinessId());
        XXXModel.setEstimatedAmount(XXXDO.getEstimatedAmount());
        XXXModel.setStatus(EnumUtils.getEnum(StatusEnum.class, XXXDO.getStatus()));
        XXXModel.setMemo(XXXDO.getMemo());
        XXXModel.setProjectType(XXXDO.getProjectType());

        return XXXModel;
    }
}

跑对应test测试

package com.qjbx.bidguaranteepolicy.test;

import com.alibaba.fastjson.JSON;
import com.google.gson.JsonObject;
import com.qjbx.bidguaranteepolicy.core.converter.BidModelConverterForTestSpring;
import com.qjbx.bidguaranteepolicy.core.model.BidModel;
import com.qjbx.bidguaranteepolicy.dal.dataobject.BidDO;
import org.junit.Test;

import java.util.Date;


public class mapstructTest {

    @Test
    public void test() {

        XXXDO XXXDO = new XXXDO();
        XXXDO.setOpenTime(new Date());
        XXXDO.setFileNo("1452");
        XXXDO.setEstimatedAmount("EstimatedAmount");
        XXXDO.setStartTime(new Date());
        XXXDO.setStatus("DISABLED");

        System.out.println( "XXXDO = {" + JSON.toJSON(XXXDO)  + "}");
        XXXModel XXXModel = new XXXModel();
        XXXModel = BidModelConverterForTestSpring.INSTANCE.convertToModelForTest(XXXDO);

        System.out.println("XXXModel = {" + JSON.toJSON(XXXModel)  + "}");

    }

}

springboot 用map接收不到参数 springboot接受map_实体类_06

猜想成功。 BidModelConverterForTestSpring 类中代码,其中上半方法是对应采用新的MapStruct方法实现,下部分是原本代码中的代码逻辑。

后续迭代可以二者都有进行迭代处理。

比如具体代码可以是

springboot 用map接收不到参数 springboot接受map_实体类_07

/** 原先的代码表现形式。某个实体类代码进去,然后转换后的代码出来 */
        bidModel = BidModelConverterForTestSpring.convertToModel(bidDO);
        /** 现在的代码形式。 可以直接在对应编写 convertToModel的代码进行整改。 对应整改名称如果不删除上面方法前提下,可以考虑添加部分后缀 比如统一添加
         * ForMapStruct 作为代码优化的标识。然后同时存在,观察是否影响线上,或者测试环境是否有效。待校验过后,可以进行代码优化,将上面直接转换 手写get/set的操作用MapStruct代替
         * */
        bidModel = BidModelConverterForTestSpring.INSTANCE.convertToModelForTest(bidDO);

7、网上部分资料整理。

springboot 用map接收不到参数 springboot接受map_java_08

springboot 用map接收不到参数 springboot接受map_java_09

一些代码的方便使用,是因为有人进行了封装,俗称语法糖。

越是get / set 基础的操作,封装越少,或者越贴近底层代码逻辑,执行效率是越高的。

8、网上已知错误参考。

关于MapStruct使用expression表达式的小坑

具体内容大致为 expression 同类型转同类型 好像确实会应用到所有的; 某个时间处理方式,可能是用到二个方法中的一个,如果让系统自动匹配,系统不会自动识别。所以这里评论区也给出了对应方法。全路径调用方法去解决。

MapStruct - Lombok & Maven 版本关系

具体内容大致为 如果采用MapStruct,可以需要提升Maven版本跟Lombok版本。对应版本号是Maven版本要3.6.0 以上;Lombok版本要在1.16.16以上。对应的MapStruct版本为 1.4.1.Final。可能是新的MapStruct需要其他更高版本的支持。 当时本次测试所用为 1.2.0.Final。无需提升Maven跟Lombok版本,也能满足目前简单转换需求。

MapStruct - No property named “XXX“ exists in source parameter(s). Did you mean “null“?

具体内容同上一个,应该也是MapStruct版本采用1.4.1.Final 高版本所引发的其他版本问题。

***

## 漫漫长路,一个小周跟他一个小陈朋友一起努力奔跑。

***