当前位置: 首页 > news >正文

使用AOP切面对返回的数据进行脱敏的问题

1.注解类

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @Author: xiaoxin* @Date: 2023/7/21 17:15*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface Encrypt {Type type() default Type.MOBILE_PHONE;enum Type {//用户idUSER_ID,//中文名CHINESE_NAME,//身份证号ID_CARD,//座机号FIXED_PHONE,//手机号MOBILE_PHONE,//地址ADDRESS,//电子邮件EMAIL,//密码PASSWORD,//中国大陆车牌,包含普通车辆、新能源车辆CAR_LICENSE,//银行卡BANK_CARD,//字符串STR}}

2.EncryptUtil工具

import cn.hutool.core.util.DesensitizedUtil;
import io.ctc.commons.tools.utils.StringUtils;import java.lang.reflect.Field;/*** @Author: xiaoxin* @Date: 2023/7/21 17:16*/
public class EncryptUtil {public static void encryptFields(Object obj) {Field[] fields = obj.getClass().getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(Encrypt.class)) {Encrypt encryptAnnotation = field.getAnnotation(Encrypt.class);Encrypt.Type type = encryptAnnotation.type();field.setAccessible(true);try {String value = (String) field.get(obj);String encryptedValue = encryptValue(type, value);field.set(obj, encryptedValue);} catch (IllegalAccessException e) {e.printStackTrace();}}}}/**** 根据类型进行脱敏处理* @param type* @param value* @return*/public static String encryptValue(Encrypt.Type type, String value) {StringBuffer sb = new StringBuffer();switch (type) {case USER_ID:sb.append(DesensitizedUtil.userId());break;case CHINESE_NAME:sb.append(DesensitizedUtil.chineseName(value));break;case ID_CARD:sb.append(DesensitizedUtil.idCardNum(value, 1, 2));break;case FIXED_PHONE:sb.append(DesensitizedUtil.fixedPhone(value));break;case MOBILE_PHONE:sb.append(DesensitizedUtil.mobilePhone(value));break;case ADDRESS:sb.append(DesensitizedUtil.address(value,6));break;case EMAIL:sb.append(DesensitizedUtil.email(value));break;case PASSWORD:sb.append(DesensitizedUtil.password(value));break;case CAR_LICENSE:sb.append(DesensitizedUtil.carLicense(value));break;case BANK_CARD:sb.append(DesensitizedUtil.bankCard(value));break;case STR:if (StringUtils.isNotBlank(encryptionStr(value))){sb.append(encryptionStr(value));}break;}return sb.toString();}/**** 自定义字符串处理* @param str* @return*/public static String encryptionStr(String str) {if (StringUtils.isBlank(str)){return "";}int length = str.length();if (length <= 4){return str;}// 替换的起始位置int startIndex = (length - 3) / 2;// 替换的结束位置int endIndex = startIndex + 3;// 替换为4个*String replacement = "****";StringBuilder sb = new StringBuilder(str);sb.replace(startIndex, endIndex, replacement);return sb.toString();}
}

3.EncryptAspect切面类

import io.ctc.commons.tools.utils.Result;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Objects;/*** @author xiaoxin*/
@Aspect
@Component
public class EncryptAspect {protected Logger logger = LoggerFactory.getLogger(getClass());@Pointcut("@annotation(io.util.test.Encrypt)")public void encryptDataPointCut() {}/**** 后置增强,返回数据脱敏切面类,页面上有部分数据是不能对外展示的,此方法不支持反脱敏* 示例:原数据19879835555   脱敏后198****5555* @param point* @throws Throwable*/@AfterReturning(value = "encryptDataPointCut()",returning = "returnValue")public void around(JoinPoint point, Object returnValue){logger.info("---------------后置增强~~~~对部分数据脱敏---------------");if (Objects.nonNull(returnValue)){//1.判断object是否可以转换为List<?>类型if (returnValue instanceof List<?>){List list = (List) returnValue;list.stream().forEach(a->{EncryptUtil.encryptFields(a);});}else//2.result对象,属性有code、msg、dataif (returnValue instanceof Result){try{Result result = (Result) returnValue;Object data = result.getData();if (Objects.nonNull(data)){if (data instanceof List<?>){List list = (List) data;list.stream().forEach(a->{EncryptUtil.encryptFields(a);});}else {EncryptUtil.encryptFields(data);}}}catch (ClassCastException e){throw new ClassCastException("数据脱敏转换失败");}}else {EncryptUtil.encryptFields(returnValue);}}}
}

4.User对象(需要脱敏的属性)

import io.util.test.Encrypt;
import lombok.Data;/*** 测试* @Author: xiaoxin* @Date: 2023/7/21 17:16*/
@Data
public class User {@Encrypt(type = Encrypt.Type.USER_ID)private String user_id;@Encrypt(type = Encrypt.Type.CHINESE_NAME)private String chinese_name;@Encrypt(type = Encrypt.Type.ID_CARD)private String id_card;@Encrypt(type = Encrypt.Type.FIXED_PHONE)private String fixed_phone;@Encrypt(type = Encrypt.Type.MOBILE_PHONE)private String mobile_phone;@Encrypt(type = Encrypt.Type.ADDRESS)private String  address;@Encrypt(type = Encrypt.Type.EMAIL)private String email;@Encrypt(type = Encrypt.Type.PASSWORD)private String password;@Encrypt(type = Encrypt.Type.CAR_LICENSE)private String car_license;@Encrypt(type = Encrypt.Type.BANK_CARD)private String bank_card;@Encrypt(type = Encrypt.Type.STR)private String str;}

5.下面为测试:

Controller

service

 结果:

 

统一返回结果就上面这样子的,controller上打上注解,实体类上根据类型打上注解就可以了。可以支持返回对象、List集合,分页的谁要的话在切面里写一下就好了,DesensitizedUtil是hutool的。

 

 

http://www.lryc.cn/news/102731.html

相关文章:

  • TDengine时区设置
  • 站外引流效果差?一文带你搞懂解海外主流社交媒体算法!
  • css 动画之旋转视差
  • maven项目、springboot项目复制文件进来后没反应、不编译解决方法
  • android jetpack App Startup 应用启动时初始化组件(java)
  • 【设计模式|行为型】命令模式(Command Pattern)
  • SqlServer 批量删除表
  • [Linux]线程基本知识
  • STM32 串口基础知识学习
  • 页面滚动时隐藏element-ui下拉框/时间弹框
  • C#中i++和++i的底层原理
  • 在win10下安装verilator
  • java设计模式-建造者(Builder)设计模式
  • iOS开发-实现获取下载主题配置动态切换主题
  • react经验4:动态组件
  • Java maven的下载解压配置(保姆级教学)
  • Java课题笔记~数据库连接池
  • 设计模式-单例模式
  • golang mysql
  • uniapp使用echarts
  • Python命令模式介绍、使用
  • #typescript 使用file-saver模块#
  • 移动端适配布局rem和vw
  • 【Java基础教程】(四十八)集合体系篇 · 上:全面解析 Collection、List、Set常用子接口及集合元素迭代遍历方式~【文末送书】
  • 什么是 DNS ANAME 解析?
  • Neo4j 集群和负载均衡
  • go web框架 gin-gonic源码解读01————Engine
  • windows版docker部署springcloud项目
  • 探索工程机械远程控制新纪元:Intewell-Hyper II震撼发布!
  • DM8 DSC集群实时主备搭建