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

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

作者头像
青衫染红尘
发布于 2021-01-19 03:34:40
发布于 2021-01-19 03:34:40
98100
代码可运行
举报
文章被收录于专栏:Surpass' BlogSurpass' Blog
运行总次数:0
代码可运行

[TOC]

本文目的

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

反射

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

使用场景

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

实现代码

服务层校验类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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+请求参数(首字母大写)”。特殊的是最后一个有两个参数,在控制器中会特殊处理,后面接着看。

反射实现控制器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何在SpringBoot项目中使用拦截器进行相关操作
​ 拦截器主要用来拦截各种请求并在拦截器中进行相应的处理,一般情况下用来进行权限校验,拦截登录转发,统一日志打印等操作。
青衫染红尘
2021/01/19
8610
教你如何使用策略模式
在策略模式中一个类的行为或者其算法在运行是可以进行改变,这种的类型也可以叫做行为型模式。
青衫染红尘
2021/01/15
1.1K0
教你如何使用策略模式
EasyExcel实现动态列解析和存表
一个表中的数据来源于多个其他系统的导出表,其中的特点就是大多数的字段都是一样的(可能导出的表头不一样),只有部分少数字段是每个系统自己独有的。围绕这个做一次功能性分析
青衫染红尘
2022/08/02
5.5K1
SpringBoot之Jpa 多数据源
前言:JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中,在Spring 2.0.1中,正式提供对JPA的支持,这也促成了JPA的发展,要知道JPA的好处在于可以分离于容器运行,变得更加的简洁。之前上一家公司就是用的jpa,感觉很简单,特别是注解的实现完全解决了xml配置的繁琐,这个案例只是一个超级简单的demo,如果需要分页和一对多关联关系需要自己查阅一下其他资料,反正我是不推荐使用join 建立表关联关系。
王念博客
2019/07/24
1.4K0
springboot 项目整合拦截器
六月的雨在Tencent
2024/03/28
1000
spring boot 如何统一处理 Filter、Servlet 中的异常信息
可以使用过滤器对请求进行预处理,预处理完毕之后,再执行 chain.doFilter() 将程序放行。
create17
2020/07/27
6K0
SpringBoot的旅游项目——day02(登录、拦截器)
    我们使用拦截器去配置权限无法做到细粒度的设置,所以我们可以使用自定义注解来控制权限。
上分如喝水
2021/08/16
3820
SpringBoot的旅游项目——day02(登录、拦截器)
springboot+security+jwt+mysql 动态权限
项目位置:https://gitee.com/huatao1994/springSecuritySeparate 一、数据库 二、controller package cn.**.controller
用户5899361
2020/12/07
1.1K0
springboot+security+jwt+mysql 动态权限
Redis排行榜的设计与实现
排行榜zset的经典实现,现在的思路全都是查库的操作,由于业务原因,有些是异步操作,难免存在已经计分,但分数还没有入库,这时去查库,导致与实际的分数不一致的情况,通常排行榜本身的操作不是很频繁,但计分的操作很频繁,但也不排除有些业务场景有些"分数怪"刷分的情况,比如王者荣耀实时排列等。
疯狂的KK
2020/09/14
2K0
Redis排行榜的设计与实现
java解析json转Map
前段时间在做json报文处理的时候,写了一个针对不同格式json转map的处理工具方法,总结记录如下:
全栈程序员站长
2022/07/02
3.4K0
如何设计一个幂等接口
问:为什么要多次操作结果都一致呢?比如我查询数据,每次查出来的都一样,即使我修改了每次查出来的也都要一样吗?
贪挽懒月
2020/06/02
1.2K0
如何设计一个幂等接口
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
特来一篇关于SpringBoot接口返回结果及异常统一处理,虽说封不封装都能用,但咱后端也得给前端小姐姐留个好印象不是。项目前后端分离,规范的数据传输格式,让REST风格的API具有简单、易读、易用的特点。不仅代码优美,也可以让带刀的前端小姐姐变得更漂亮。以下例子参考多个实际项目,最终总结来跟大家进行分享,大佬勿喷。
JavaDog程序狗
2024/10/07
1.8K0
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
springboot第23集:login与register代码流程
生成随机数,我发现生成5位随机数时,如果开头为0,发送的短信只有4位,这里开头加个1,保证短信的正确性
达达前端
2023/10/08
2500
springboot第23集:login与register代码流程
SpringBoot集成支付宝 - 少走弯路就看这篇
在开始集成支付宝支付之前,我们需要准备一个支付宝商家账户,如果是个人开发者,可以通过注册公司或者让有公司资质的单位进行授权,后续在集成相关API的时候需要提供这些信息。
码老思
2023/10/19
5430
SpringBoot集成支付宝 - 少走弯路就看这篇
【第十一篇】SpringSecurity基于JWT实现Token的处理
  前面介绍了手写单点登录和JWT的应用,本文结合SpringSecurity来介绍下在SpringBoot项目中基于SpringSecurity作为认证授权框架的情况下如何整合JWT来实现Token的处理。
用户4919348
2022/05/27
1.2K0
【第十一篇】SpringSecurity基于JWT实现Token的处理
SpringMVC【校验器、统一处理异常、RESTful、拦截器】
前言 本博文主要讲解的知识点如下: 校验器 统一处理异常 RESTful 拦截器 Validation 在我们的Struts2中,我们是继承ActionSupport来实现校验的…它有两种方式来实现校
Java3y
2018/04/02
1.5K0
SpringMVC【校验器、统一处理异常、RESTful、拦截器】
微信支付之扫码、APP、小程序支付接入详解
做电商平台的小伙伴都知道,支付服务是必不可少的一部分,今天我们开始就说说支付服务的接入及实现。目前在国内,几乎90%中小公司的支付系统都离不开微信支付和支付宝支付。那么大家要思考了,为什么微信支付和支付宝支付能作为大多数公司接入的首选呢?其实这个问题大多小伙伴应该是很清楚的,说白了就是人家有庞大的用户流量,目前微信在国内的用户已突破10亿,支付宝也接近8亿左右,如此庞大的用户群体,你还会选择其他的第三方支付(微博钱包、财付通、快钱等)吗,作为普通客户,大家都希望能方便快捷,谁会为了在一个平台买点东西下载或开通其他服务呢,除非你给他有诱惑性的好处。今天我们先说说微信支付的接入及实现。
攻城狮的那点事
2019/08/26
2.1K0
微信支付之扫码、APP、小程序支付接入详解
SpringCloud(七) - 微信支付
1、开发文档 微信开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 安全规范:https://pay.weixin.q
化羽羽
2022/11/16
3470
SpringCloud(七) - 微信支付
Spring Security 在 Spring Boot 中集成 JWT + RSA【分布式】
  分布式认证就是我们常说的单点登录(SSO),即用户只需要登录一次就可以访问所有互相信任的子系统。在每台服务中都有一个 session 但是各个 session 之间时无法共享资源的,所以 session 不能作为单点登录的解决方案。单点登录一般分为两个部分:  ♞ 用户认证:这一环节主要是用户向认证服务发起认证请求,认证服务给用户返回一个成功的令牌 token,主要在认证服务中完成,注意认证服务只能有一个。  ♞ 身份校验:这一环节是用户携带 token 去访问其他服务时,在其他服务中要对 token 的真伪进行检验,主要在资源服务中完成,资源服务可以有很多个。
Demo_Null
2020/10/28
3.2K0
Spring Security 在 Spring Boot 中集成 JWT + RSA【分布式】
分布式服务 API 的幂等设计方案 & Spring Boot + Redis 拦截器实现实例
假如你有个服务提供一个接口,结果这个服务部署在了5台机器上,接着有个接口就是付款接口。
一个会写诗的程序员
2021/04/02
8580
相关推荐
如何在SpringBoot项目中使用拦截器进行相关操作
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验