前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot使用反射对业务代码进行统一处理

SpringBoot使用反射对业务代码进行统一处理

作者头像
青衫染红尘
发布2021-01-19 11:34:40
8600
发布2021-01-19 11:34:40
举报
文章被收录于专栏:Surpass' BlogSurpass' Blog

[TOC]

本文目的

使用反射在SpringBoot中对多个校验接口进行统一操作

反射

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

使用场景

项目那个有多个校验接口:比如身份证校验,手机号校验等,如果每个都对该次校验写一个校验方法,如果后期又出现其他组合的校验,最后会很繁琐,代码冗余,难以维护。那么这里使用反射对每个校验方法进行统一的操作,根据请求操作来判断使用那几个组合的校验方法。后期如果有新的校验添加起来也就很方便,容易维护。

实现代码

服务层校验类

public interface BlackValidateService {
    /**
     * @Description: 根据手机号判断是否在黑名单中
     * @param phone
     * @return com.p4.risk.entity.RiskRetCode
     * @author Surpass
     * @date 2020/12/2 13:56
     */
    RiskRetCode getPhone(String phone);

    /**
     * @Description: 根据身份证号判断是否在黑名单中
     * @param idCardNum
     * @return com.p4.risk.entity.RiskRetCode
     * @author Surpass
     * @date 2020/12/2 13:56
     */
    RiskRetCode getIdCardNum(String idCardNum);

    /**
     * @Description: 根据终端号判断是否在黑名单中
     * @param termNo
     * @return com.p4.risk.entity.RiskRetCode
     * @author Surpass
     * @date 2020/12/2 13:56
     */
    RiskRetCode getTermNo(String termNo);

    /**
     * @Description: 根据银行卡号判断是否在黑名单中
     * @param cardNum
     * @return com.p4.risk.entity.RiskRetCode
     * @author Surpass
     * @date 2020/12/2 13:57
     */
    RiskRetCode getCardNum(String cardNum);

    /**
     * @Description: 根据营业执照号判断是否在黑名单中
     * @param busLicenseNo
     * @return com.p4.risk.entity.RiskRetCode
     * @author Surpass
     * @date 2020/12/2 13:57
     */
    RiskRetCode getBusLicenseNo(String busLicenseNo);

    /**
     * @Description: 根据基站号,小区号判断是否在黑名单中
     * @param stationNo
     * @param cellId
     * @return com.p4.risk.entity.RiskRetCode
     * @author Surpass
     * @date 2020/12/2 13:57
     */
    RiskRetCode getBaseStation(String stationNo, String cellId);
}

说明:返回值类型是一个枚举类,返回键值对数据像00、99之类的,实现类就是校验逻辑了,接口方法统一使用“get+请求参数(首字母大写)”。特殊的是最后一个有两个参数,在控制器中会特殊处理,后面接着看。

反射实现控制器

@Slf4j
@RestController
@RequestMapping("/mposDataValidate")
public class MposDataValidateController {

    /**
     * mpos黑名单校验方法
     */
    @Autowired
    private BlackValidateService validate;

    private Gson gson = new Gson();

    /**
     * @Description: 利用反射将黑名单方法和参数进行绑定,根据参数key不同来查询不同的黑名单
     * @param param 需要校验的参数:idCardNum,termNo,cardNum,busLicenseNo,stationNo,cellId,phone
     * @return java.util.Map<java.lang.String , java.lang.Object>
     * @author Surpass
     * @date 2020/12/2 13:22
     */
    @RequestMapping("/dataValidator")
    public Map<String,Object> dataValidator(@RequestBody Map<String,Object> param){
        log.info("mpos外放接口调用,校验黑名单传入参数:"+gson.toJson(param));
        Map<String, Object> resultMap = new HashMap<>(2);
        if (param.size() == 0){
            resultMap.put("rspCode","99");
            resultMap.put("rspMsg","接口数据参数为空");
            log.info("接口数据参数为空");
            return resultMap;
        }
        try {
            //基站号参数key
            String stationNo = "stationNo";
            //小区号参数key
            String cellId = "cellId";
            //基站黑名单方法名
            String baseStationMethodName = "getBaseStation";
            //基站号参数value
            String stationNoVal = null;
            //小区号参数value
            String cellIdVal = null;
            RiskRetCode result = null;
            //获得接口校验的class类对象
            Class<BlackValidateService> cls = BlackValidateService.class;
            //遍历参数
            for (Map.Entry<String, Object> entry : param.entrySet()) {
                String key = entry.getKey();
                String value = (String) entry.getValue();
                if (StringUtils.isBlank(value)){
                    continue;
                }
                //基站信息特殊处理
                if ((stationNo).equals(key)){
                    stationNoVal = value;
                    continue;
                }
                if ((cellId).equals(key)){
                    cellIdVal = value;
                    continue;
                }
                //根据参数key获取方法名   getPhone...
                String methodsName = "get"+key.substring(0,1).toUpperCase()+key.substring(1);
                //根据方法名和方法参数确定某一个方法
                Method method = cls.getMethod(methodsName, String.class);
                //执行,对方法进行访问赋值
                result = (RiskRetCode)method.invoke(validate, value);

                if (Objects.equals(result.getValue(), RiskRetCode.R00.getValue())){
                    //校验通过,进行下一个  00通过
                    resultMap.put("rspCode",RiskRetCode.R00.getValue());
                    resultMap.put("rspMsg",result.getDesc());
                    continue;
                }else {
                    //在黑名单中,直接返回    99不通过
                    resultMap.put("rspCode",RiskRetCode.R99.getValue());
                    resultMap.put("rspMsg",result.getDesc());
                    return resultMap;
                }
            }
            //基站需要基站号和小区号
            if (StringUtils.isNotEmpty(stationNoVal) && StringUtils.isNotEmpty(cellIdVal)){
                //根据方法名和方法参数确定某一个方法
                Method method = cls.getMethod(baseStationMethodName, String.class, String.class);
                //执行,对方法进行访问赋值
                result = (RiskRetCode)method.invoke(validate, stationNoVal,cellIdVal);
            }
            if (Objects.equals(result.getValue(), RiskRetCode.R00.getValue())){
                resultMap.put("rspCode",RiskRetCode.R00.getValue());
                resultMap.put("rspMsg",result.getDesc());
            }else {
                resultMap.put("rspCode",RiskRetCode.R99.getValue());
                resultMap.put("rspMsg",result.getDesc());
                return resultMap;
            }
        }catch (Exception e){
            log.error("mpos外放接口黑名单校验异常",e);
            resultMap.put("rspCode",RiskRetCode.R99.getValue());
            resultMap.put("rspMsg","mpos外放接口黑名单校验异常");
            return resultMap;
        }
        if (resultMap.size() == 0){
            resultMap.put("rspCode", RiskRetCode.R99.getValue());
            resultMap.put("rspMsg", "本次请求没有过任何黑名单接口");
        }
        log.info("mpos外放接口调用,校验黑名单返回参数:"+gson.toJson(resultMap));
        return resultMap;
    }

}

说明:每一个接口校验都会通过参数来判断,特别的基站则需要基站小区两个都存在才会去校验,那么只需要单独判断一下就可以。代码注释还是比较详细的。

尾言

其实当时博主是没有想到使用反射来做的,当收到任务时只想到了怎么if()if()的,哈哈哈,还是大佬告诉我,怎么轻巧,怎么统一,才想到能够这个样子做的,觉得眼光短浅,只注重了眼前,所以接到任务还是需要多思考思考,多回顾回顾,这样子才能成长,一起加油吧!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本文目的
  • 反射
  • 使用场景
  • 实现代码
    • 服务层校验类
      • 反射实现控制器
      • 尾言
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档