不同模块调用服务时Bean传参问题

分享dataBean不同导致的方法传参问题(以需求做讲解)

基础数据

A模块定义的BeanA

package com.fspdfcy;

import java.io.Serializable;
import java.util.Objects;

/**
 * @author fsp
 * @version 1.0
 * @date 2022/11/11
 * @since test
 */
public class BeanA implements Serializable {
    private static final long serialVersionUID = 1L;

    private String id;
    private String name;
    private String type;
    private int count;
    // 独有属性,区分BeanB
    private String ofOwn1;
    private String ofOwn2;
    private String ofOwn3;
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getOfOwn1() {
        return ofOwn1;
    }

    public void setOfOwn1(String ofOwn1) {
        this.ofOwn1 = ofOwn1;
    }

    public String getOfOwn2() {
        return ofOwn2;
    }

    public void setOfOwn2(String ofOwn2) {
        this.ofOwn2 = ofOwn2;
    }

    public String getOfOwn3() {
        return ofOwn3;
    }

    public void setOfOwn3(String ofOwn3) {
        this.ofOwn3 = ofOwn3;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BeanA beanA = (BeanA) o;
        return count == beanA.count && Objects.equals(id, beanA.id) && Objects.equals(name, beanA.name) && Objects.equals(type, beanA.type) && Objects.equals(ofOwn1, beanA.ofOwn1) && Objects.equals(ofOwn2, beanA.ofOwn2) && Objects.equals(ofOwn3, beanA.ofOwn3);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, type, count, ofOwn1, ofOwn2, ofOwn3);
    }

    @Override
    public String toString() {
        return "BeanA{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", type='" + type + '\'' +
                ", count=" + count +
                ", ofOwn1='" + ofOwn1 + '\'' +
                ", ofOwn2='" + ofOwn2 + '\'' +
                ", ofOwn3='" + ofOwn3 + '\'' +
                '}';
    }
}

B模块定义的BeanB

package com.fspdfcy;

import java.util.Objects;

/**
 * @author fsp
 * @version 1.0
 * @date 2022/11/11
 * @since test
 */
public class BeanB {
    private static final long serialVersionUID = 1L;

    private String id;
    private String name;
    private String type;
    private int count;
    // 独有属性,区分BeanA
    private String ofOwn4;
    private String ofOwn5;
    private String ofOwn6;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getOfOwn4() {
        return ofOwn4;
    }

    public void setOfOwn4(String ofOwn4) {
        this.ofOwn4 = ofOwn4;
    }

    public String getOfOwn5() {
        return ofOwn5;
    }

    public void setOfOwn5(String ofOwn5) {
        this.ofOwn5 = ofOwn5;
    }

    public String getOfOwn6() {
        return ofOwn6;
    }

    public void setOfOwn6(String ofOwn6) {
        this.ofOwn6 = ofOwn6;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BeanB beanB = (BeanB) o;
        return count == beanB.count && Objects.equals(id, beanB.id) && Objects.equals(name, beanB.name) && Objects.equals(type, beanB.type) && Objects.equals(ofOwn4, beanB.ofOwn4) && Objects.equals(ofOwn5, beanB.ofOwn5) && Objects.equals(ofOwn6, beanB.ofOwn6);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, type, count, ofOwn4, ofOwn5, ofOwn6);
    }

    @Override
    public String toString() {
        return "BeanB{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", type='" + type + '\'' +
                ", count=" + count +
                ", ofOwn4='" + ofOwn4 + '\'' +
                ", ofOwn5='" + ofOwn5 + '\'' +
                ", ofOwn6='" + ofOwn6 + '\'' +
                '}';
    }
}

业务需求:传入BeanA集合或BeanB集合,根据name和type(都有这两个属性)根据业务逻辑结束后填入count字段,但私有属性不能丢失。
一开始的思路:定义BeanC,将BeanA和BeanB的所有属性加载BeanC中,然后方法定义入参BeanC,在调用服务的时候使用BeanUtils将BeanA和BeanB转换为BeanC(理论可行,但未去实现)
问题在于,如果其他模块定义了其他bean,但都要调用这个服务的时候这就是地狱了,不具备通用性。

解决方案

方法接收List<T> list,将list转化为map,再根据通用属性处理业务逻辑(使用map.get(“name”)),处理完成写入count(使用map.put(“count”,22)),最后将处理完成的数据转换回去并返回,这样不会导致数据的丢失,且具备通用性。
定义转换类 ConvertUtil (当然也可以使用第三方工具类)

package com.fspdfcy;

import com.alibaba.fastjson.JSON;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author fsp
 * @version 1.0
 * @date 2022/11/11
 * @since test
 */
public class ConvertUtil {
    private ConvertUtil() {
        throw new RuntimeException("工具类不能实例化");
    }

    public static <T> void makeMapToObject(Map<String, Object> map, T obj) {
        Objects.requireNonNull(map);
        Class<?> aClass = obj.getClass();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String filedName = entry.getKey();
            String methodName = "set" + filedName.toUpperCase().charAt(0) + filedName.substring(1);
            try {
                if (entry.getValue() != null) {
                    Method setMethod = aClass.getDeclaredMethod(methodName, entry.getValue().getClass());
                    setMethod.invoke(obj, entry.getValue());
                }
            } catch (Exception e) {
                // e.printStackTrace();      // 正常异常,无需打印
            }
        }
    }

    public static <T> T makeMapToObject(Map<String, Object> map, Class<T> clazz) {
        Objects.requireNonNull(map);
        T obj = null;
        try {
            obj = clazz.newInstance();
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String filedName = entry.getKey();
                String methodName = "set" + filedName.toUpperCase().charAt(0) + filedName.substring(1);
                try {
                    if (entry.getValue() != null) {
                        Method setMethod = clazz.getDeclaredMethod(methodName, entry.getValue().getClass());
                        setMethod.invoke(obj, entry.getValue());
                    }
                } catch (Exception e) {
                    // e.printStackTrace();      // 正常异常,无需打印
                }
            }
        } catch (Exception e) {
             e.printStackTrace();      // 正常异常,无需打印
        }
        return obj;
    }

    public static <T> List<T> makeMapListTpObjectList(List<Map<String, Object>> mapList, Class<T> clazz) {
        Objects.requireNonNull(mapList);
        List<T> list = new ArrayList<>(mapList.size());
        mapList.forEach(map -> {
            list.add(makeMapToObject(map, clazz));
        });
        return list;
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> makeObjectMap(Object obj) {
        return (Map<String, Object>) JSON.toJSON(obj);
    }

    @SuppressWarnings("unchecked")
    public static <T> List<Map<String, Object>> makeObjectListToMapList(List<T> objectList) {
        return (List<Map<String, Object>>) JSON.toJSON(objectList);
    }
}

服务接口

package com.fspdfcy.service;

import java.util.List;

/**
 * @author fsp
 * @version 1.0
 * @date 2022/11/11
 * @since test
 */
public interface Service {
    <T> List<T> doSomething(List<T> list);
}


服务实现

package com.fspdfcy.service.impl;

import com.fspdfcy.ConvertUtil;
import com.fspdfcy.service.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author fsp
 * @version 1.0
 * @date 2022/11/11
 * @since test
 */
public class ServiceImpl implements Service {

    @Override
    @SuppressWarnings("unchecked")
    public <T> List<T> doSomething(List<T> list) {
        // 为空直接返回
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> mapList = ConvertUtil.makeObjectListToMapList(list);
        // 业务逻辑xxx
        String name = mapList.get(0).get("name").toString();
        String type = mapList.get(0).get("type").toString();
        // 填入count
        mapList.forEach(map -> {
            map.put("count", 2);
        });
        return (List<T>) ConvertUtil.makeMapListToObjectList(mapList, list.get(0).getClass());
    }
}

测试

package com.fspdfcy.service.impl;

import com.fspdfcy.ConvertUtil;
import com.fspdfcy.service.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author fsp
 * @version 1.0
 * @date 2022/11/11
 * @since test
 */
public class ServiceImpl implements Service {

    @Override
    @SuppressWarnings("unchecked")
    public <T> List<T> doSomething(List<T> list) {
        // 为空直接返回
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> mapList = ConvertUtil.makeObjectListToMapList(list);
        // 业务逻辑xxx
        String name = mapList.get(0).get("name").toString();
        String type = mapList.get(0).get("type").toString();
        // 填入count
        mapList.forEach(map -> {
            map.put("count", 2);
        });
        return (List<T>) ConvertUtil.makeMapListToObjectList(mapList, list.get(0).getClass());
    }
}

结果

[BeanA{id='a1', name='a1', type='a1', count=0, ofOwn1='a1', ofOwn2='a1', ofOwn3='a1'}, BeanA{id='a2', name='a2', type='a2', count=0, ofOwn1='a2', ofOwn2='a2', ofOwn3='a2'}, BeanA{id='a3', name='a3', type='a3', count=0, ofOwn1='a3', ofOwn2='a3', ofOwn3='a3'}]
[BeanB{id='b1', name='b1', type='b1', count=0, ofOwn4='b1', ofOwn5='b1', ofOwn6='b1'}, BeanB{id='b2', name='b2', type='b2', count=0, ofOwn4='b2', ofOwn5='b2', ofOwn6='b2'}, BeanB{id='b3', name='b3', type='b3', count=0, ofOwn4='b3', ofOwn5='b3', ofOwn6='b3'}]

可能有仔细的人已经发现问题了,就是count没有改变,对,这就是我要抛出的重要点,dataBean需要全部都是引用类型,引用类型,引用类型。因为在转为为mapList的时候自动装箱了,然后在转化为beanList的时候其实是报错找不到方法com.fspdfcy.BeanB.setCount(java.lang.Integer)
所以解决办法就是将BeanA和BeanB所有的基本数据类型转换为包装类,就能解决问题了。
附上修改后的结果

[BeanA{id='a1', name='a1', type='a1', count=2, ofOwn1='a1', ofOwn2='a1', ofOwn3='a1'}, BeanA{id='a2', name='a2', type='a2', count=2, ofOwn1='a2', ofOwn2='a2', ofOwn3='a2'}, BeanA{id='a3', name='a3', type='a3', count=2, ofOwn1='a3', ofOwn2='a3', ofOwn3='a3'}]
[BeanB{id='b1', name='b1', type='b1', count=2, ofOwn4='b1', ofOwn5='b1', ofOwn6='b1'}, BeanB{id='b2', name='b2', type='b2', count=2, ofOwn4='b2', ofOwn5='b2', ofOwn6='b2'}, BeanB{id='b3', name='b3', type='b3', count=2, ofOwn4='b3', ofOwn5='b3', ofOwn6='b3'}]

至此,完美解决问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值