我之前写了一篇关于使用注解和策略模式实现数据脱敏功能,其中使用策略模式用来消除if语句,实现业务与条件逻辑的解耦,有利于功能的扩展。

使用策略模式实现数据脱敏:
简单回顾下这篇文章的脱敏功能,原数据:
- public UserInfo getUserInfo() {
- UserInfo userInfo = new UserInfo();
- userInfo.setAge(23);
- userInfo.setIdCard("32133458888988771");
- userInfo.setMobile("13456782345");
- userInfo.setNativePlace("北京海定区");
- userInfo.setSex("男");
- userInfo.setUseId(1234567L);
- userInfo.setUseName("爱德华");
- userInfo.setUseNo("11");
- return userInfo;
- }
要求对身份证和手机号实现数据脱敏
- @Data
- public class UserInfo {
- private Long useId;
-
- /**
- * 用户编号
- */
- private String useNo;
-
- /**
- * 用户姓名
- */
- private String useName;
-
- /**
- * 用户手机号
- */
- @SensitiveInfo(SensitiveType.MOBILE_PHONE)
- private String mobile;
-
- /**
- * 用户性别
- */
- private String sex;
-
- /**
- * 用户年龄
- */
- private int age;
-
- /**
- * 用户籍贯
- */
- private String nativePlace;
-
- /**
- * 用户身份证
- */
- @SensitiveInfo(SensitiveType.ID_CARD)
- private String idCard;
-
- }
这里对脱敏的字段标上了脱敏注解。
脱敏效果

代码中有用if语句处理各个类型的脱敏,这是一般情况,使用if语句将业务代码与条件代码混到一起,不利于类型的拓展,这个问题上篇文章有讲到。

解决办法是使用了策略模式消除了if语句。今天我们来使用规则引擎消除if语句,代码案例同样是脱敏功能实现。
规则引擎就是提供一种可选的计算模型。与通常的命令式模型(由带有条件和循环的命令依次组成)不同,规则引擎基于生产规则系统。这是一组生产规则,每条规则都有一个条件(condition)和一个动作(action)———— 简单地说,可以将其看作是一组if-then语句。
精妙之处在于规则可以按任何顺序编写,引擎会决定何时使用对顺序有意义的任何方式来计算它们。考虑它的一个好方法是系统运行所有规则,选择条件成立的规则,然后执行相应的操作。

Easy Rules是一个开源的规则引擎框架,它提供Rule抽象以创建具有条件和动作的规则,并提供RuleEngine API,该API通过一组规则运行以评估条件并执行动作。
- <!--规则引擎-->
- <dependency>
- <groupId>org.jeasy</groupId>
- <artifactId>easy-rules-core</artifactId>
- <version>4.0.0</version>
- </dependency>
我们编写了如下的规则类:

接口用于规范规则方法


这里在类上定义Rule注解,表明Rule的名称和描述。类里面实现3个方法:
getCurrentSensitiveType():获取当前的枚举类型
isCurrentType():规则判断,方法上标上@Condition注解,说明这个方法是规则判断的条件。参数中的@Fact注解,可以将条件方法中的参数传到下面的执行方法中。
maskingData():执行方法,标上@Action注解,当isCurrentType()为真时,会执行该方法。

我通过规则接口获取所有的规则实现类实例,然后注意注册到规则引擎中,最后执行规则。我们来看看详细的执行过程。
想要执行规则,我们首先需要创建一个Fact实例,这个实例用于存储条件判断的参数。
Fact内部是一个HashSet容器:

name的值我们可以自定义,value的值是脱敏注解传过来的信息。
接着需要将Rule实例注册到Rules中,这里我们通过Spring的特性获取到了接口SensitiveRule的所有示例:

最后执行Rule,当规则满足,就会执行规则定义的方法:

RuleEntity实体类内容
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- @ToString
- public class RuleEntity {
- SensitiveType type;
- String infoStr;
- }
RuleMapService中的map存放处理后的脱敏数据
- public class RuleMapService {
- public static Map<String, String> getMap() {
- return map;
- }
-
- private static Map<String,String> map = Maps.newHashMap();
- }
调用RuleService#execute方法,处理脱敏数据:

最后效果:

我们看到电话号码和身份证信息做了脱敏处理。
本篇文章简要的介绍如何使用规则引擎消除if语句,实现数据脱敏。关于规则引擎的详细使用可以看看这篇文章:
[Easy-Rules: Easy Rules 是开源的 Java 规则引擎 (gitee.com)]-(https://gitee.com/mirrors/Easy-Rules)
关于规则引擎使用代码可以私信我获取。
如果这篇文章对你有所帮助,欢迎点赞和转发。