运用JAVA AOP和反射实现接口配置化

 一. 项目背景:

 对于原来提供给外部公司调用的接口有一个默认的接口文档(标注了默认的必填字段), 提供一个接口可配置的界面, 可以将有些非必填的值设置为必填, 还有给原来必填字段默认值或者根据其他字段的值设置当前值的赋值规则. 总结来说,有如下三条规则:

a.可以将原来接口文档里的非必填字段改成必填字段,

b.修改必填字段的默认值(外部调用不用再传此字段,系统自动按配置默认)

c.修改必填字段的默认值,根据配置的规则,根据其他字段替换掉接口字段中的值

二. 项目设计:

1.前端回显原来默认接口文档, 后端保存初始化接口文档json 格式,前端解析成页面

2.后端保存前端设置的规则并存到DB, 设计三张表: 接口初始化json存在常量表pic_b_constant, 接口配置表pic_b_interface_config, 接口配置规则表 pic_b_interface_config_template . 其中pic_b_constant存初始化接口json 文件(可以当成系统常量表使用), pic_b_interface_config表存了前端封装的全量json 信息;  接口配置规则表则是解析了前端传来的json ,保存接口对应的每条规则.

3.在管理后台产品经理可以对接口配置规则(未配置规则则按原来默认HTML样式展示)

4.代码中新建自定义注解,加到需要应用的方法上面

5.再环绕通知里面通过注解判断是否走规则. 若进入规则则按规则根据接口入参分别增加必填校验,默认值和应用规则(这里面要用到java 的反射机制)

三. 最终效果:

 

 

注:

①.因为接口入参里面嵌套了多层对象.,我们现在仅考虑到里面第二层,在注入参数值的时候要注意getDeclaredFields()和 getFields()的区别. 

②在赋值的时候要根据入参类型进行赋值,不然会出现类转换异常

③处理入参为空,但是要赋默认值或者应用规则的情况

四. 相关代码如下:

  • 自定义注解

import java.lang.annotation.*;

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoParamRule {
    String type() default "";
}
  • 应用接口上面加注解
 @AutoParamRule(type = "contImp")
  • 切面
package com.riskeys.pic.policyservice.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.riskeys.common.base.exception.BizException;
import com.riskeys.common.util.StringUtil;
import com.riskeys.pic.config.annotation.AutoParamRule;
import com.riskeys.pic.config.base.PicBaseRequestDTO;
import com.riskeys.pic.config.dto.newcont.apply.ApplicantInfoDTO;
import com.riskeys.pic.config.dto.newcont.apply.ApplyNewContRequestDTO;
import com.riskeys.pic.config.dto.newcont.apply.InsuredInfoDTO;
import com.riskeys.pic.config.dto.newcont.apply.PayReceivedDTO;
import com.riskeys.pic.policyservice.dao.primary.PicBInterfaceConfigMapper;
import com.riskeys.pic.policyservice.dao.primary.PicBInterfaceConfigTemplateMapper;
import com.riskeys.pic.policyservice.model.bean.PicBInterfaceConfigBean;
import com.riskeys.pic.policyservice.model.bean.PicBInterfaceConfigTemplateBean;
import com.riskeys.pic.policyservice.model.interfaceConfig.FieldRules;
import com.riskeys.pic.policyservice.util.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @ClassName AutoParamRuleAspect
 * @Description
 * @Author Ken
 * @Date 2023/2/22 9:48
 * @Version V1.0.1
 */
@Order(1)
@Component
@Slf4j
@Aspect
public class AutoParamRuleAspect {

    @Resource
    private PicBInterfaceConfigMapper picBInterfaceConfigMapper;

    @Resource
    private PicBInterfaceConfigTemplateMapper picBInterfaceConfigTemplateMapper;

    @Pointcut("@annotation(com.riskeys.pic.config.annotation.AutoParamRule)")
    public void serviceAspect() {

    }

    /**
     * @return java.lang.Object
     * @Title: 环绕通知
     * @Author: ken
     * @Description:
     * @Date: 2023/3/16  15:37
     * @Param: [pjp, autoParamRule
     **/
    @Around("serviceAspect() && @annotation(autoParamRule)")
    public Object doAround(ProceedingJoinPoint pjp, AutoParamRule autoParamRule) throws Throwable {
        //获取所有参数
        Object[] args = pjp.getArgs();
        log.info("[AutoParamRuleAspect --> around begin]- args[0]:{}", JSONObject.toJSONString(args[0]));

        String type = autoParamRule.type();
        if (type.equals("contImp")) {
            Object object = args[0];
            PicBaseRequestDTO picBaseRequestDTO = (PicBaseRequestDTO) object;
            //  PicBaseRequestDTO PicBaseRequestDTO = JSONObject.parseObject(object.toString(), PicBaseRequestDTO.class);
            log.info("[AutoParamRuleAspect -->  doAround]- picBaseRequestDTO:{}", JSONObject.toJSONString(picBaseRequestDTO));

            ApplyNewContRequestDTO applyNewContRequestDTO = JSON.parseObject(JSON.toJSONString(picBaseRequestDTO.getBody()), ApplyNewContRequestDTO.class);
            if (Objects.isNull(applyNewContRequestDTO)) {
                log.info("[AutoParamRuleAspect -->  doAround]- applyNewContRequestDTO is null");
                return pjp.proceed(args);
            }
            ApplicantInfoDTO applicantInfoDTO = applyNewContRequestDTO.getApplicant();
            List<InsuredInfoDTO> insureds = applyNewContRequestDTO.getInsureds();
            PayReceivedDTO payReceivedDTO = applyNewContRequestDTO.getPayInfo();
            //JSONObject extendsInfo = new JSONObject(applyNewContRequestDTO.getExtendInfo());
            HashMap<String, Object> extendInfo = applyNewContRequestDTO.getExtendInfo();
            //查询出所有必填字段和规则
            String sourceCode = picBaseRequestDTO.getHeader().getSourceCode();
            QueryWrapper<PicBInterfaceConfigBean> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("source_code", sourceCode);
            queryWrapper.eq("is_delete", 0);
            List<PicBInterfaceConfigBean> picBInterfaceConfigBeanList = picBInterfaceConfigMapper.selectList(queryWrapper);
            if (CollectionUtils.isEmpty(picBInterfaceConfigBeanList)) {
                log.info("[AutoParamRuleAspect -->  doAround]- picBInterfaceConfigBeanList is null");
                return pjp.proceed(args);
            }

            PicBInterfaceConfigBean picBInterfaceConfigBean = picBInterfaceConfigBeanList.get(0);
            Integer sid = picBInterfaceConfigBean.getSid();
            QueryWrapper<PicBInterfaceConfigTemplateBean> queryWrappers = new QueryWrapper<>();
            queryWrappers.eq("interface_id", sid);
            queryWrappers.eq("is_delete", 0);
            List<PicBInterfaceConfigTemplateBean> picBInterfaceConfigTemplateBeanList = picBInterfaceConfigTemplateMapper.selectList(queryWrappers);
            if (CollectionUtils.isEmpty(picBInterfaceConfigTemplateBeanList)) {
                log.info("[AutoParamRuleAspect -->  doAround]- picBInterfaceConfigTemplateBeanList is null");
                return pjp.proceed(args);
            }

            ApplyNewContRequestDTO applyNewContRequestDTOs = new ApplyNewContRequestDTO();
            ApplicantInfoDTO applicantInfoDTOs = new ApplicantInfoDTO();
            List<InsuredInfoDTO> insuredInfoDTOs = Lists.newArrayList();
            //若传入 insureds 为空时会用到
            InsuredInfoDTO insured = new InsuredInfoDTO();
            PayReceivedDTO payReceivedDTOs = new PayReceivedDTO();
            HashMap<String, Object> extendInfos = Maps.newHashMap();

            //先校验必填字段 Check required fields
            List<PicBInterfaceConfigTemplateBean> addRequiredFieldList = picBInterfaceConfigTemplateBeanList.stream()
                    .filter(p -> p.getTemplateType().equals(3)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(addRequiredFieldList)) {
                for (PicBInterfaceConfigTemplateBean addRequiredField : addRequiredFieldList) {
                    String parentField = addRequiredField.getInterfaceParentField();
                    String currField = addRequiredField.getInterfaceField();
                    if ("baseInfo".equals(parentField)) {
                        String fieldValue = String.valueOf(getFieldValueByName(applyNewContRequestDTO, currField));
                        if(Objects.isNull(applyNewContRequestDTO)){
                            throw new BizException("基本信息为空(基本信息下有必填字段)");
                        }
                        checkRequiredFields(parentField, currField, fieldValue);
                    } else if ("applicant".equals(parentField)) {
                        String fieldValue = String.valueOf(getFieldValueByName(applicantInfoDTO, currField));
                        if(Objects.isNull(applicantInfoDTO)){
                            throw new BizException("投保人信息为空(投保人信息下有必填字段)");
                        }
                        checkRequiredFields(parentField, currField, fieldValue);
                    } else if ("insureds".equals(parentField)) {
                        if (!CollectionUtils.isEmpty(insureds)) {
                            for (InsuredInfoDTO insuredInfoDTO : insureds) {
                                String fieldValue = String.valueOf(getFieldValueByName(insuredInfoDTO, currField));
                                if(Objects.isNull(insuredInfoDTO)){
                                    throw new BizException("被保人信息为空(被保人信息下有必填字段)");
                                }
                                checkRequiredFields(parentField, currField, fieldValue);
                            }
                        }
                    } else if ("payInfo".equals(parentField)) {
                        String fieldValue = String.valueOf(getFieldValueByName(payReceivedDTO, currField));
                        if(Objects.isNull(payReceivedDTO)){
                            throw new BizException("支付信息为空(支付信息下有必填字段)");
                        }
                        checkRequiredFields(parentField, currField, fieldValue);
                    } else if ("extendInfo".equals(parentField)) {
                        if(CollectionUtils.isEmpty(extendInfo)){
                            throw new BizException("扩展信息为空(扩展信息下有必填字段)");
                        }
                        String fieldValue = String.valueOf(extendInfo.get(currField));
                        checkRequiredFields(parentField, currField, fieldValue);
                    } else {
                        log.info("[AutoParamRuleAspect -->  doAround]- error parentField: {} ", parentField);
                    }
                }
            }

            //校验规则: 1: 设置默认值
            List<PicBInterfaceConfigTemplateBean> requiredDefaultValueFieldList = picBInterfaceConfigTemplateBeanList.stream()
                    .filter(p -> p.getTemplateType().equals(1)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(requiredDefaultValueFieldList)) {
                for (PicBInterfaceConfigTemplateBean addRequiredField : requiredDefaultValueFieldList) {
                    String parentField = addRequiredField.getInterfaceParentField();
                    String currField = addRequiredField.getInterfaceField();
                    String defaultValue = addRequiredField.getDefaultValue();
                    if ("baseInfo".equals(parentField)) {
                        // 获取该类的成员变量
                        Field f = applyNewContRequestDTOs.getClass().getDeclaredField(currField);
                        // 取消语言访问检查
                        f.setAccessible(Boolean.TRUE);
                        String fieldType = f.getType().getTypeName();
                        // 给变量赋值 (需判断传入参数是否为空)
                        if(Objects.isNull(applyNewContRequestDTO)){
                            f.set(applyNewContRequestDTOs, ObjectUtils.convertAttributeValue(fieldType, defaultValue));
                        }else{
                            f.set(applyNewContRequestDTO, ObjectUtils.convertAttributeValue(fieldType, defaultValue));
                        }
                    } else if ("applicant".equals(parentField)) {
                        Field f = getAllField(applicantInfoDTOs.getClass(), currField);
                        f.setAccessible(Boolean.TRUE);
                        String fieldType = f.getType().getTypeName();
                        // 给变量赋值 (需判断传入参数是否为空)
                        if(Objects.isNull(applicantInfoDTO)){
                            f.set(applicantInfoDTOs, ObjectUtils.convertAttributeValue(fieldType, defaultValue));
                        }else{
                            f.set(applicantInfoDTO, ObjectUtils.convertAttributeValue(fieldType, defaultValue));
                        }
                    } else if ("insureds".equals(parentField)) {
                        if (!CollectionUtils.isEmpty(insureds)) {
                            for (InsuredInfoDTO insuredInfoDTO : insureds) {
                                Field f = getAllField(insuredInfoDTO.getClass(), currField);
                                f.setAccessible(Boolean.TRUE);
                                String fieldType = f.getType().getTypeName();
                                f.set(insuredInfoDTO, ObjectUtils.convertAttributeValue(fieldType, defaultValue));
                            }
                        }else{
                            Field f = getAllField(insured.getClass(), currField);
                            f.setAccessible(Boolean.TRUE);
                            String fieldType = f.getType().getTypeName();
                            f.set(insured, ObjectUtils.convertAttributeValue(fieldType, defaultValue));
                        }
                    } else if ("payInfo".equals(parentField)) {
                        Field f = payReceivedDTOs.getClass().getDeclaredField(currField);
                        f.setAccessible(Boolean.TRUE);
                        String fieldType = f.getType().getTypeName();

                        // 给变量赋值 (需判断传入参数是否为空)
                        if(Objects.isNull(payReceivedDTO)){
                            f.set(payReceivedDTOs, ObjectUtils.convertAttributeValue(fieldType, defaultValue));
                        }else{
                            f.set(payReceivedDTO, ObjectUtils.convertAttributeValue(fieldType, defaultValue));
                        }
                    } else if ("extendInfo".equals(parentField)) {

                        if(Objects.isNull(extendInfo)){
                            extendInfos.put(currField, defaultValue);
                        }else{
                            extendInfo.put(currField, defaultValue);
                        }
                    } else {
                        log.info("[AutoParamRuleAspect -->  doAround]- error parentField: {} ", parentField);
                    }
                }
            }
            //校验规则: 2: 替换原来的值
            List<PicBInterfaceConfigTemplateBean> requiredRuleFieldList = picBInterfaceConfigTemplateBeanList.stream()
                    .filter(p -> p.getTemplateType().equals(2) && !StringUtil.isEmpty(p.getRule())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(requiredRuleFieldList)) {
                //全部规则节点
                Map<String, List<PicBInterfaceConfigTemplateBean>> map = requiredRuleFieldList.stream().collect(
                Collectors.groupingBy(o -> o.getInterfaceParentField()+':'+o.getInterfaceField()));
                Set<String> sets = map.keySet();

                //匹配到规则的节点
                Set<String> set = Sets.newHashSet();
                List<String> ruleList = requiredRuleFieldList.stream().map(PicBInterfaceConfigTemplateBean::getRule).collect(Collectors.toList());
                log.info("[AutoParamRuleAspect -->  doAround]- ruleList: {} ", JSONObject.toJSONString(ruleList));
                for (String rule : ruleList) {
                    FieldRules fieldRule = JSON.parseObject(rule, FieldRules.class);
                    //被替换值 节点信息 eg: "fieldCode": "jobInfo", "fieldCodeParentId": "extendInfo"}, "value2": "b"
                    String fieldCode = fieldRule.getFieldCode();
                    String fieldCodeParentId = fieldRule.getFieldCodeParentId();
                    String value2 = fieldRule.getValue2();
                    //替换值 节点信息 eg: "field": "contractCompanyCode", "parentId": "baseInfo", "value": "a"
                    String field = fieldRule.getField();
                    String parentId = fieldRule.getParentId();
                    String value = fieldRule.getValue();

                    if ("baseInfo".equals(fieldCodeParentId)) {
                        // 获取该类的成员变量
                        Field f = applyNewContRequestDTOs.getClass().getDeclaredField(fieldCode);

                        // 基准变量的值
                        String baseValue = "";
                        if ("baseInfo".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(applyNewContRequestDTO, field));
                        } else if ("applicant".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(applicantInfoDTO, field));
                        } else if ("insureds".equals(parentId)) {
                            if (!CollectionUtils.isEmpty(insureds)) {
                                baseValue = String.valueOf(getFieldValueByName(insureds.get(0), field));
                            }
                        } else if ("payInfo".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(payReceivedDTO, field));
                        } else if ("extendInfo".equals(parentId)) {
                            baseValue = String.valueOf(extendInfo.get(field));
                        } else {
                            log.info("[AutoParamRuleAspect -->  doAround]- error fieldCodeParentId: {} ", fieldCodeParentId);
                        }

                        String fieldType = f.getType().getTypeName();
                        if (value.equals(baseValue)) {
                            set.add(fieldCodeParentId + ":" + fieldCode);
                            // 取消语言访问检查
                            f.setAccessible(Boolean.TRUE);
                            if(Objects.isNull(applyNewContRequestDTO)){
                                f.set(applyNewContRequestDTOs, ObjectUtils.convertAttributeValue(fieldType, value2));
                            }else{
                                f.set(applyNewContRequestDTO, ObjectUtils.convertAttributeValue(fieldType, value2));
                            }
                        }
                    } else if ("applicant".equals(fieldCodeParentId)) {
                        // 获取该类的成员变量
                        Field f = getAllField(applicantInfoDTOs.getClass(), fieldCode);
                        // 基准变量的值
                        String baseValue = "";
                        if ("baseInfo".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(applyNewContRequestDTO, field));
                        } else if ("applicant".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(applicantInfoDTO, field));
                        } else if ("insureds".equals(parentId)) {
                            if (!CollectionUtils.isEmpty(insureds)) {
                                baseValue = String.valueOf(getFieldValueByName(insureds.get(0), field));
                            }
                        } else if ("payInfo".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(payReceivedDTO, field));
                        } else if ("extendInfo".equals(parentId)) {
                            baseValue = String.valueOf(extendInfo.get(field));
                        } else {
                            log.info("[AutoParamRuleAspect -->  doAround]- error fieldCodeParentId: {} ", fieldCodeParentId);
                        }

                        String fieldType = f.getType().getTypeName();
                        if (value.equals(baseValue)) {
                            set.add(fieldCodeParentId + ":" + fieldCode);
                            // 取消语言访问检查
                            f.setAccessible(Boolean.TRUE);
                            if(Objects.isNull(applicantInfoDTO)){
                                f.set(applicantInfoDTOs, ObjectUtils.convertAttributeValue(fieldType, value2));
                            }else{
                                f.set(applicantInfoDTO, ObjectUtils.convertAttributeValue(fieldType, value2));
                            }
                        }
                    } else if ("insureds".equals(fieldCodeParentId)) {
                        if (!CollectionUtils.isEmpty(insureds)) {
                            for (InsuredInfoDTO insuredInfoDTO : insureds) {
                                Field f = getAllField(insuredInfoDTO.getClass(),fieldCode);

                                // 基准变量的值
                                String baseValue = "";
                                if ("baseInfo".equals(parentId)) {
                                    baseValue = String.valueOf(getFieldValueByName(applyNewContRequestDTO, field));
                                } else if ("applicant".equals(parentId)) {
                                    baseValue = String.valueOf(getFieldValueByName(applicantInfoDTO, field));
                                } else if ("insureds".equals(parentId)) {
                                    baseValue = String.valueOf(getFieldValueByName(insuredInfoDTO, field));
                                } else if ("payInfo".equals(parentId)) {
                                    baseValue = String.valueOf(getFieldValueByName(payReceivedDTO, field));
                                } else if ("extendInfo".equals(parentId)) {
                                    baseValue = String.valueOf(extendInfo.get(field));
                                } else {
                                    log.info("[AutoParamRuleAspect -->  doAround]- error fieldCodeParentId: {} ", fieldCodeParentId);
                                }

                                String fieldType = f.getType().getTypeName();
                                if (value.equals(baseValue)) {
                                    set.add(fieldCodeParentId + ":" + fieldCode);
                                    f.setAccessible(Boolean.TRUE);
                                    f.set(insuredInfoDTO, ObjectUtils.convertAttributeValue(fieldType, value2));
                                }
                            }
                        }else{
                            Field f = getAllField(insured.getClass(), fieldCode);
                            f.setAccessible(Boolean.TRUE);
                            String fieldType = f.getType().getTypeName();
                            f.set(insured, ObjectUtils.convertAttributeValue(fieldType, value2));
                        }

                    } else if ("payInfo".equals(fieldCodeParentId)) {
                        // 获取该类的成员变量
                        Field f = payReceivedDTOs.getClass().getDeclaredField(fieldCode);

                        // 基准变量的值
                        String baseValue = "";
                        if ("baseInfo".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(applyNewContRequestDTO, field));
                        } else if ("applicant".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(applicantInfoDTO, field));
                        } else if ("insureds".equals(parentId)) {
                            if (!CollectionUtils.isEmpty(insureds)) {
                                baseValue = String.valueOf(getFieldValueByName(insureds.get(0), field));
                            }
                        } else if ("payInfo".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(payReceivedDTO, field));
                        } else if ("extendInfo".equals(parentId)) {
                            baseValue = String.valueOf(extendInfo.get(field));
                        } else {
                            log.info("[AutoParamRuleAspect -->  doAround]- error fieldCodeParentId: {} ", fieldCodeParentId);
                        }

                        String fieldType = f.getType().getTypeName();
                        if (value.equals(baseValue)) {
                            set.add(fieldCodeParentId + ":" + fieldCode);
                            // 取消语言访问检查
                            f.setAccessible(Boolean.TRUE);
                            if(Objects.isNull(payReceivedDTO)){
                                f.set(payReceivedDTOs, ObjectUtils.convertAttributeValue(fieldType, value2));
                            }else{
                                f.set(payReceivedDTO, ObjectUtils.convertAttributeValue(fieldType, value2));
                            }
                        } else {
                            log.info("[AutoParamRuleAspect -->  doAround]- error fieldCodeParentId: {} ", fieldCodeParentId);
                        }
                    } else if ("extendInfo".equals(fieldCodeParentId)) {
                        // 基准变量的值
                        String baseValue = "";
                        if ("baseInfo".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(applyNewContRequestDTO, field));
                        } else if ("applicant".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(applicantInfoDTO, field));
                        } else if ("insureds".equals(parentId)) {
                            if (!CollectionUtils.isEmpty(insureds)) {
                                baseValue = String.valueOf(getFieldValueByName(insureds.get(0), field));
                            }
                        } else if ("payInfo".equals(parentId)) {
                            baseValue = String.valueOf(getFieldValueByName(payReceivedDTO, field));
                        } else if ("extendInfo".equals(parentId)) {
                            baseValue = String.valueOf(extendInfo.get(field));
                        } else {
                            log.info("[AutoParamRuleAspect -->  doAround]- error fieldCodeParentId: {} ", fieldCodeParentId);
                        }

                        if (value.equals(baseValue)) {
                            set.add(fieldCodeParentId + ":" + fieldCode);
                            extendInfo.put(fieldCode, value2);
                            if(Objects.isNull(extendInfo)){
                                extendInfos.put(fieldCode, value2);
                            }else{
                                extendInfo.put(fieldCode, value2);
                            }
                        } else {
                            log.info("[AutoParamRuleAspect -->  doAround]- error fieldCodeParentId: {} ", fieldCodeParentId);
                        }
                    }
                }

                sets.removeAll(set);
                if(!CollectionUtils.isEmpty(sets)){
                    Iterator it = sets.iterator();
                    while(it.hasNext()){
                        String [] fields = it.next().toString().split(":");
                        String parentField = fields[0];
                        String currField = fields[1];
                        String msg = String.format("参数父节点 ParentField: %s->当前节点currField: %s设置了规则,但未匹配到任何规则,请检查规则设置", parentField, currField);
                        throw new BizException(msg);
                    }
                }
            }
            //判断传入字段为空b
            if(Objects.isNull(applicantInfoDTO)){
                applyNewContRequestDTO.setApplicant(applicantInfoDTOs);
            }else{
                applyNewContRequestDTO.setApplicant(applicantInfoDTO);
            }

            if(CollectionUtils.isEmpty(insureds)){
                insuredInfoDTOs.add(insured);
                applyNewContRequestDTO.setInsureds(insuredInfoDTOs);
            }else{
                applyNewContRequestDTO.setInsureds(insureds);
            }

            if(Objects.isNull(applicantInfoDTO)){
                applyNewContRequestDTO.setApplicant(applicantInfoDTOs);
            }else{
                applyNewContRequestDTO.setApplicant(applicantInfoDTO);
            }

            if(Objects.isNull(extendInfo)){
                applyNewContRequestDTO.setExtendInfo(extendInfos);
            }else{
                applyNewContRequestDTO.setExtendInfo(extendInfo);
            }
            picBaseRequestDTO.setBody(Objects.isNull(applyNewContRequestDTO)?applyNewContRequestDTOs:applyNewContRequestDTO);
            args[0] = picBaseRequestDTO;
        }

        log.info("[AutoParamRuleAspect --> around end]- args[0]:{}", JSONObject.toJSONString(args[0]));

        return pjp.proceed(args);
    }

    /**
     * @Title: 校验必填字段
     * @Author: ken
     * @Description:
     * @Date: 2023/3/24  18:46
     * @Param: [parentField, currField, fieldValue]
     * @return void
     **/
    private void checkRequiredFields(String parentField, String currField, String fieldValue) {
        log.info("[AutoParamRuleAspect -->  doAround]- parentField:{}, fieldValue: {} ", parentField, fieldValue);
        if (StringUtil.isEmpty(fieldValue)) {
            throw new BizException("参数父节点 ParentField:" + parentField + "->当前节点currField:" + currField + "不能为空");
        }
    }

    /**
     * @return java.lang.Object
     * @Title: changObjectValue
     * @Author: ken
     * @Description: .getSuperclass()
     * @Date: 2023/3/18  16:13
     * @Param: [obj, filedName, afterValue]
     **/
    private Object changObjectValue(Object obj, String filedName, Object afterValue) throws Exception {
        //获取父类的字段,因为capCode放在在基类里面,这里就直接获取父类的Class了,
        //参数只在当前类的可以添加当前类的逻辑
        Field[] fieldInfo = obj.getClass().getDeclaredFields();
        for (Field field : fieldInfo) {
            if (filedName.equals(field.getName())) {
                //成员变量为private,故必须进行此操
                field.setAccessible(true);
                Object fieldValue = field.get(obj);
                field.set(obj, afterValue);
                break;
            }
        }
        return obj;
    }

    /**
     * 获取对象指定属性的值
     *
     * @param o         对象
     * @param fieldName 要获取值的属性
     *                  返回值:对象指定属性的值
     */
    public Object getFieldValueByName(Object o, String fieldName) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            return value;
        } catch (Exception e) {
            log.error("AutoParamRuleAspect --> getFieldValueByName error:{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * @return java.lang.reflect.Field
     * @Title: 根据属性名获取字段(当前类及父类)
     * @Author: ken
     * @Description:
     * @Date: 2023/3/24  14:41
     * @Param: [clazz, filedName]
     **/
    public static Field getAllField(Class<?> clazz, String filedName) {
        try {
            if (clazz != null) {
                return clazz.getDeclaredField(filedName);
            }
        } catch (NoSuchFieldException e) {
            return getAllField(clazz.getSuperclass(), filedName);
        }
        return null;
    }
}

仅供参考.

公众号搜索: 果酱桑,一起成长,一起进步!

附 示例接口:

请求方式 POST

参数类型 `["application/json"]

接口描述 产品中心保单导入

请求报文体

ApplyNewContRequestDTO

参数名称

参数说明

是否必须

数据类型

schema

contNo

保单号

true

string

contractCompanyCode

签约机构编码

true

string

必填代码上没有控制,如果传的话 会校验是否在 pic_b_insurance_company(保险公司定义表)是否存在

sessionId

可回溯会话id

false

string

versionId

可回溯版本id

false

string

actualPrem

实付保费

true

int

单位(分)

amount

保额

true

Long

单位(分)

prem

保费金额

true

int

单位(分)

productCode

产品编码

true

string

由阳光提供

planCode

计划编码

true

string

由阳光提供

applyDate

投保时间

true

string

格式:yyyy-MM-dd HH:mm:ss

contAcceptDate

保单承保日期

true

string

格式:yyyy-MM-dd HH:mm:ss

efftiveDate

保单起期

true

string

格式:yyyy-MM-dd HH:mm:ss

expireDate

保单失效日期

true

string

格式:yyyy-MM-dd HH:mm:ss

insurancePeriod

保险期间

true

int

保单的保障期限。配合保险期间单位使用,例如:保险期间单位为:Y,保险期间:1.则1年

insuranceUnit

保险期间单位

true

string

见6.5期间单位

payIntv

缴费频率

true

string

缴费方式 见6.6缴费频率 

payPeriod

缴费期间

true

int

配合缴费期间单位使用,例如:缴费期间单位为:Y,缴费期间:1.则1年缴

payPeriodUnit

缴费期间单位

true

string

见6.5期间单位

applicant

投保人信息

true

ApplicantInfoDTO

ApplicantInfoDTO

payInfo

订单回录:支付数据

false

PayReceivedDTO

PayReceivedDTO

insureds

被保人列表

true

array

InsuredInfoDTO

extendInfo

扩展信息

false

object

见扩展信息说明

commissionRate

佣金比例

false

String

例:佣金比例为30%,则传30

commissionPrem

佣金费佣金金额_含税

false

String

单位(分)

settlementDate

结算时间

false

String

由阳光提供,格式:yyyy-MM-dd HH:mm:ss

projectMainId

项目编码

false

String

由阳光提供

ApplicantInfoDTO

参数名称

参数说明

是否必须

数据类型

schema

appType

投保人类型

true

string

"01", "个人","02", "企业"

name

投保人名称

true

string

gender

性别

false

string

见6.7性别 证件非身份证必传

birthday

生日

false

string

证件非身份证必传,yyyy-MM-dd

certNo

证件号码

true

string

certType

证件类型

true

string

见6.2证件类型

height

身高

false

integer(int32)

weight

体重

false

number

phone

手机号

false

string

email

邮箱

false

string

nationality

国籍

false

string

certValidDate

证件有效期

false

string

yyyy-MM-dd

longTremFlag

证件长期有效标记

false

string

nameEn

英文姓名

false

string

nameItem

false

string

nameItemEn

英文名

false

string

surname

false

string

surnameEn

英文姓

false

string

extendInfo

拓展json字段

false

object

InsuredInfoDTO

参数名称

参数说明

是否必须

数据类型

schema

name

被保人名称

true

string

gender

性别

false

string

证件非身份证必传

birthday

生日

false

string

证件非身份证必传,yyyy-MM-dd

certNo

证件号码

true

string

certType

证件类型

true

string

见6.2证件类型

certValidDate

证件有效期

false

string

yyyy-MM-dd

longTremFlag

证件长期有效标记

false

string

phone

手机号

false

string

email

邮箱

false

string

medicalInsurance

医保状态

false

string

见6.9有无医保

socialInsurance

社保状态

false

string

见6.8有无社保

marriage

婚姻状况

false

string

nationality

国籍

false

string

fixedFlag

是否固定收入标记

false

string

familyAnnualIncome

家庭年收入

false

string

annualIncome

年收入

false

string

relaWithApp

与投保人关系

true

string

见6.3关系类型

relaWithMainIns

与主被保人关系

false

string

见6.3关系类型

height

身高

false

integer(int32)

weight

体重

false

BigDecimal

prem

被保人保费

true

integer(int32)

单位(分)

amount

被保人保额

true

integer(int32)

单位(分)

nameEn

英文姓名

false

string

nameItem

false

string

nameItemEn

英文名

false

string

surname

false

string

surnameEn

英文姓

false

string

benefitType

受益人类型

true

string

"01", "法定","02", "指定"。如指定受益人 需传受益人列表benefits 相关参数

benefits

受益人列表

false

array

BenefitInfoDTO,如指定受益人类型:02-指定,则必传

riskList

险种列表

false

array

RiskInfoDTO

signPath

签名影像地址

false

string

filePathBack

影像反面地址

false

string

filePathFront

影像正面地址

false

string

extendInfo

拓展json字段

false

object

见扩展信息说明

BenefitInfoDTO

参数名称

参数说明

是否必须

数据类型

schema

name

受益人姓名

false

string

nameEn

英文姓名

false

string

nameItem

false

string

nameItemEn

英文名

false

string

surname

false

string

surnameEn

英文姓

false

string

gender

性别

true

string

birthday

生日

false

string

certNo

证件号码

true

string

certType

证件类型

true

string

见6.2证件类型

certValidDate

证件有效期

false

string

longTremFlag

证件长期有效标记

false

string

phone

手机号

false

string

email

邮箱

false

string

nationality

国籍

false

string

percent

受益份额

true

integer(int32)

0~100,加总=100

priority

受益顺序

true

integer(int32)

relationWithInured

与被保人关系

true

string

见6.3关系类型

signPath

签名影像地址

false

string

filePathBack

影像反面地址

false

string

filePathFront

影像正面地址

false

string

extendInfo

拓展json字段

false

object

RiskInfoDTO

参数名称

参数说明

是否必须

数据类型

schema

riskCode

险种编号

TRUE

string

riskCount

险种数量

TRUE

integer(int32)

prem

险种保费

TRUE

integer(int32)

单位(分)

amount

险种保额

TRUE

integer(int32)

单位(分)

effectPeriod

保障期限

FALSE

integer(int32)

effectPeriodUnit

保障期限单位

FALSE

string

effectTime

险种起期

FALSE

string

expireTime

险种止期

FALSE

string

mainRiskFlag

主险标记

FALSE

boolean

dutyList

责任列表

TRUE

array

DutyInfoDTO

DutyInfoDTO

参数名称

参数说明

是否必须

数据类型

schema

dutyName

责任名称

true

string

dutyCode

责任编码

true

string

dutyType

责任类型

true

string

dutyCount

责任份数

true

integer(int32)

dutyPrem

责任保费

true

integer(int32)

单位(分)

dutyAmount

责任保额

true

integer(int32)

单位(分)

subDedu

次免赔额

true

integer(int32)

单位(分)

yearDedu

年免赔额

true

integer(int32)

单位(分)

PayReceivedDTO

参数名称

参数说明

是否必须

数据类型

schema

paymentId

支付id

true

string

outTradeNo

商户支付号

true

string

payNo

商户支付单号

true

string

orderAmount

订单金额

true

integer(int32)

单位(分)

payAmount

支付金额

true

integer(int32)

单位(分)

subsidyAmount

折扣金额

false

integer(int32)

单位(分)

payType

支付方式

false

string

payMethod

支付方法

false

string

payState

支付状态

true

string

payTime

支付时间

true

string

yyyy-MM-dd HH:mm:ss

accountName

账户名称

false

string

accountNo

账户号

false

string

accountType

账户类型

false

string

bankCode

银行编码

false

string

payDesc

支付描述

false

string

createDate

创建时间

false

string(date-time)

yyyy-MM-dd HH:mm:ss

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值