利用java反射,实现明细导入对品牌的校验

从事开发有两年了,一直没有什么记录。刚好最近有接了一个需求,用到了java反射以及抽象的一些概念,觉得自己应该记录一些,已做备忘。也真诚的希望能够对读者有所帮助

1.原始需求

在明细导入的时候,通过主表品牌字段,对导入的数据做校验。

2.分析需求

1.导入是以excel的形式,往系统内录入数据。我需要考虑,关于导入校验的点。

2.在做导入的时候,我第一步必然需要抓取到我主表的数据。因为我需要通过主表的数据,来获取我对应的需要校验的字段(品牌)。

3.导入的excel,是客户自定义的模版。我具体要对商品进行做校验,但是导入的时候,我可能输入另外一个值,而这个值能够表示商品,但是他的维度本身可能比商品小(PS:以服装行业来说,我能用sku去具体的描述一个商品),这里就要做一步转化。

4.我的导入面向的是所有的业务单据,因此我的代码需要足够的抽象,去实现这些功能。

3.具体实现

1.关于导入校验的点,我是放在数据组装完成,在保存之前。最一开始的时候,我一直想把这个校验放在前面做,后来发现这个数据不全,最后干脆把它放在数据组装完成后,再去对这个导入的数据做校验。

2.明细的录入,他本身不是悬浮的,他必然要和主表做一个关联。具体的体现,就是外键。在实际开发过程中,我确实在我的明细表里找到了我的主表id,但是比较尴尬的是,我的每一个明细所对应的主表的ID的名称,都不一样。我不可能,在抽象化的过程中,具体去拿我具象的子类信息。于是,我只能在明细的javaBean中,注册两个get方法,用于记录主表的Id明细和主表的Bean。当然这里也运用到了,相关反射的思想,因为我操作的一直都是一个AbstractBean类。这个我待会会贴代码。

3.这里的信息的转化,就是纯粹业务上的转化了,根据实际业务的去进行编写。

4.代码

先看一下javaBean的代码,没啥好说的,其实就是两个get方法,我一直很好奇,为什么以前没有这个需求。

这里说一下,所有的明细都继承一个抽象的AbstractDetailBean。

public class SaleOrderGoodsDetail extends GoodsDetailBaseBean implements IE3GoodsDetailBean {

    private static final long serialVersionUID = 2159298026054804534L;
    /** 批发销货订单商品明细id */
    private String saleOrderGoodsDetailId;
    /** 批发销货订单id */
    private String saleOrderBillId;
    /** 数量 */
    private Integer qty;
    /** 计划交货日期 */
    private Date deliveryDate;
    /** 未执行数 */
    private Integer qtyTodo;
    /** 已通知数 */
    private Integer qtyAsn;
    /** 已出库数 */
    private Integer qtyOut;
    /** 未出库数 */
    private Integer qtyOutDiff;
    /** 待出库数 */
    private Integer qtyOutNoSettle;
    /** 商品code */
    private String code;
    /** 原订单数量 */
    private Integer originalQty;
    /** 变更数 */
    private Integer changeQty;
    
    /** 省略相关get/set方法 **/
    public String getParentBillBeanName() {
        return "SaleOrderBill";
    }
    
    public String getParentBillIdName() {
        return "saleOrderBillId";
    }

}

2.具体校验的代码逻辑

public ServiceResult validateBrand(String token,ServiceResult result) {
        //1.若导入失败,或者不需要校验。则直接返回
        if(result.hasError()) {
            return result;
        }
        List<Object> datas = result.getSuccessObject();
        Object parentBillBeanName = null;
        Object parentBillIdName = null;
        Object parentBillIdValue = null;
        List<Object> goodsList = new ArrayList<Object>();
        List<Object> singleProductList = new ArrayList<Object>();
        //2.通过明细javaBean 反射拿到我父类单据的bean,父类Id,以及goods和singleProduct    
        for(Object data : datas) {
            if(parentBillBeanName==null||parentBillIdName==null||parentBillIdValue==null) {
                parentBillBeanName = getMethod(data,"parentBillBeanName");
                parentBillIdName = getMethod(data,"parentBillIdName");
                if(parentBillIdName!=null) {
                    parentBillIdValue = getMethod(data,parentBillIdName.toString());
                }
            }
            Object goodsId = getMethod(data,"goodsId");
            Object singleProductId = getMethod(data,"singleProductId");
            if(goodsId!=null) {
                goodsList.add(getMethod(data,"goodsId"));
            }
            if(singleProductId!=null) {
                singleProductList.add(getMethod(data,"singleProductId"));
            }
        }
        if(parentBillBeanName==null||parentBillIdName==null||parentBillIdValue==null) {
            return result;
        }
        
        //若明细导入既无单品又无商品 则返回
        if(CollectionUtil.isEmpty(goodsList)&&CollectionUtil.isEmpty(singleProductList)) {
            return result;
        }
        
        //3.通过反射拿到父类对象和对应的brandId
        List<AbstractBean> billDatas = getParentBillObj(parentBillBeanName,parentBillIdName,parentBillIdValue);
        Brand brand = getBrandFromObj(billDatas);
        if(brand==null) {
            return result;
        }
        
        //4.明细导入仅有单品没有商品,则将单品转为商品,做数据过滤
        if(CollectionUtil.isEmpty(goodsList)&&!CollectionUtil.isEmpty(singleProductList)) {
            goodsList = getGoodsIdBySingleProduct(token,singleProductList);
        }
        
        //5.将商品做品牌过滤
        E3Goods[] noMatchGoods = validateGoodsNoMatchBrand(token,brand,goodsList);
        if(noMatchGoods!=null&&noMatchGoods.length>0) {

            //错误信息提示,需要动态显示是什么品牌

result.addErrorObject("ImportDetailsBrandValidate",ManageErrorCode.IMPORT_032,      StringUtil.format(ResourceUtils.get(ManageErrorCode.IMPORT_032), brand.getName()));
        }
        
        return result;
    }

然后,具体的反射用到了这个方法。

/**
     * 根据属性,获取get方法
     * @param field 属性名
     * @param ob 
     * @return
     */
    private static Object getMethod(Object ob, String field) {
        String str1 = field.substring(0, 1);
        String str2 = field.substring(1, field.length());
        String method_set = "get" + str1.toUpperCase() + str2;
        Method method = null;
        try {
            method = ob.getClass().getMethod(method_set);
            return method.invoke(ob);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

 

基本上就是这些了,我们老大经常告诫我们,拿到需求要进行分析,将他拆分出一点一点,然后将他转化成开发需要做些什么。

最后,希望自己在代码的道路上走的更远。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值