策略模式+责任链模式配合Nacos实现参数校验链

news/2024/9/6 6:10:07 标签: java

1、业务场景

在SpringBoot项目中,针对接收的参数信息,根据需求要进行以下校验:

  • 校验客户的apikey是否合法;
  • 校验请求的ip地址是否是白名单;
  • 校验短信的签名;
  • 校验短信的模板;
  • 校验手机号的格式合法性;
  • 校验客户剩余的金额是否充足。

2、实现分析

对于接口需要校验的参数和信息,为了保证校验的方式做到动态可插拔,而且有利于后期的扩展,参考了Mybatis二级缓存的源码,采用策略模式+责任链模式的套路。实现的大致流程是向上声明一个接口,提供校验方法,然后后编写多个校验的实现类,在执行校验时,会拿到所有的校验接口实现类,然后以责任链的形式一个个校验执行。而且,配合Nacos提供的配置动态刷新,指定校验链执行的内容,需要改变时,只需要修改Nacos的配置参数。

3、代码编写

下面是整个校验链路的代码骨架,不涉及校验条件的具体实现细节。

1. 校验的父接口
/**
 * 做策略模式的父接口
 */
public interface CheckFilter {
    /**
     * 校验方法
     * @param obj
     */
    void check(Object obj);

}
2. 准备校验的实现类
/**
 * 校验客户的apikey是否合法
 */
@Service(value = "apikey")
@Slf4j
public class ApiKeyCheckFilter implements CheckFilter {
    @Override
    public void check(Object obj) {
        log.info("【接口模块-校验apikey】");
    }
}

/**
 * 校验请求的ip地址是否是白名单
 */
@Service(value = "ip")
@Slf4j
public class IPCheckFilter implements CheckFilter {
    @Override
    public void check(Object obj) {
        log.info("【接口模块-校验ip】");
    }
}

/**
 * 校验短信的签名
 */
@Service(value = "sign")
@Slf4j
public class SignCheckFilter implements CheckFilter {
    @Override
    public void check(Object obj) {
        log.info("【接口模块-校验签名】");
    }
}

/**
 * 校验短信的模板
 */
@Service(value = "template")
@Slf4j
public class TemplateCheckFilter implements CheckFilter {
    @Override
    public void check(Object obj) {
        log.info("【接口模块-校验模板】");
    }
}

/**
 * 校验手机号的格式合法性
 */
@Service(value = "mobile")
@Slf4j
public class MobileCheckFilter implements CheckFilter {

    @Override
    public void check(Object obj) {
        log.info("【接口模块-校验手机号】");
    }
}

/**
 * 校验客户剩余的金额是否充足
 */
@Service(value = "fee")
@Slf4j
public class FeeCheckFilter implements CheckFilter {
    @Override
    public void check(Object obj) {
        log.info("【接口模块-校验客户余额】");
    }
}
3. 准备上下文对象,拿到所有的校验接口实现类
/**
 * 策略模式的上下文对象
 */
@Component
@RefreshScope
public class CheckFilterContext {
    // Spring的IOC会将对象全部都放到Map集合中
    // 基于4.x中Spring提供的反省注解,基于Map只拿到需要的类型对象即可
    @Autowired
    private Map<String,CheckFilter> checkFiltersMap;

    // 基于Nacos获取到执行的顺序和需要执行的校验对象
    @Value("${filters:apikey,ip,sign,template}")
    private String filters;

    /**
     * 当前check方法用于管理校验链的顺序
     */
    public void check(Object obj){
        //1. 将获取到filters基于,做切分
        String[] filterArray = filters.split(",");
        //2. 遍历数组即可
        for (String filter : filterArray) {
            CheckFilter checkFilter = checkFiltersMap.get(filter);
            checkFilter.check(obj);
        }
    }
}
4. Nacos配置校验执行顺序
# 校验策略的执行内容和顺序 apikey,ip,sign,template,mobile,fee
filters: apikey,ip,sign,template,mobile,fee
5. 上下文对象的使用
@RestController
public class CheckController{
    @Autowired
    private CheckFilterContext checkFilterContext;
    /**
    * 测试使用 
    */
    @PostMapping
    public void check(Object obj){
        checkFilterContext.check(obj);
    }
}

http://www.niftyadmin.cn/n/5302532.html

相关文章

Java基础-----集合类(三)

文章目录 1. Arraylist2. Arraylist常用方法 今天主要学习集合类框架 1. Arraylist Collection:是List和Set的父接口&#xff0c;里面包含了一些公用的方法 List:是一个有序的、不唯一的接口 ArrayList&#xff1a;是List的一个实现类&#xff0c;底层数据结构是数组 public…

作为产品经理,如何分析和管理产品需求?

实际工作中&#xff0c;需求分析和需求管理能力是产品经理的基础能力&#xff0c;那么该如何进行需求分析和管理呢&#xff1f; 需求分析阶段的核心可以总结为两句话&#xff1a;“这个需求能不能做&#xff1f;做成什么样&#xff1f;”。 一、需求收集 需求收集环节需要针…

炼丹学习笔记1---openPCDet训练配置参数含义介绍

背景&#xff1a;最近偷闲学习openPCDet&#xff0c;记录一下基本训练可能用到的一些配置。以下为个人学习探索&#xff0c;仅供参考。 1、cfg_file 含义&#xff1a; 指定用于训练的配置文件&#xff0c;其中包含了模型、优化器、学习率等相关的配置信息。 作用&#xff1a;…

vue3如何实现动态路由

首先明白什么是动态路由&#xff0c;路由的触发往往是由菜单决定的&#xff0c;那么就要先理解什么是动态菜单&#xff0c;动态菜单就是说每个用户的角色不同&#xff0c;看到的菜单&#xff0c;往往也是不同的&#xff0c;管理员看到的肯定会多一些&#xff0c;那么因为有不同…

AI实景无人直播创业项目:开启自动直播新时代,一部手机即可实现财富增长

在当今社会&#xff0c;直播已经成为了人们日常生活中不可或缺的一部分。无论是商家推广产品、明星互动粉丝还是普通人分享生活&#xff0c;直播已经渗透到了各行各业。然而&#xff0c;传统直播方式存在着一些不足之处&#xff0c;如需现场主持人操作、高昂的费用等。近年来&a…

力扣labuladong一刷day51天单调栈应用

力扣labuladong一刷day51天单调栈应用 一、239. 滑动窗口最大值 题目链接&#xff1a;https://leetcode.cn/problems/sliding-window-maximum/ 思路&#xff1a;滑动窗口最大值&#xff0c;既要维护加入的时间顺序&#xff0c;又要 class Solution {public int[] maxSliding…

Go语言的几种类型转换

前言 在日常编程中&#xff0c;类型转换是经常需要用到的。因此本文将总结归纳一下Go语言中常见的一些类型转换。 Go语言中的类型转换可以有多种分类方式&#xff1a; 比如按照是否需要声明&#xff0c;可以分为&#xff1a;隐式类型转换和显式类型转换。 可以再根据使用场景划…

高德地图经纬度坐标导出工具

https://tool.xuexiareas.com/map/amap 可以导出单个点&#xff0c;也可以导出多个&#xff0c;多个点可以连成线&#xff0c;可用于前端开发时自己模拟“线“数据