返回顶部
首页 > 资讯 > 精选 >SpringBoot怎么新增脱敏功能
  • 410
分享到

SpringBoot怎么新增脱敏功能

2023-07-04 17:07:36 410人浏览 独家记忆
摘要

这篇“SpringBoot怎么新增脱敏功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springBoot怎么新增脱敏功能

这篇“SpringBoot怎么新增脱敏功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springBoot怎么新增脱敏功能”文章吧。

SpringBoot项目中新增脱敏功能

项目背景

目前正在开发一个SpringBoot项目,此项目有WEB端和微信小程序端。web端提供给工作人员使用,微信小程序提供给群众进行预约操作。项目中有部分敏感数据需要脱敏传递给微信小程序,给与群众查看。

项目需求描述

项目中,由于使用端有两个,对于两个端的数据权限并不一样。Web端可以查看所有数据,小程序端只能查看脱敏后的数据。

需要开发一个通用脱敏功能

  • 手动进行脱敏操作

  • 支持多种对象,

  • 支持不同字段,并脱敏指定字段

  • 字段的脱敏方式多样

  • 字段的脱敏方式可自定义

项目解决方案

1. 解决方案

使用注解方式,来支持对指定字段,不同字段,多种脱敏操作,并可以脱离对象。
使用工具对象,通过泛型传参,来支持对不同对象的脱敏操作。

2. 实现代码

2.1 注解 Sensitive
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface Sensitive {        SensitiveType type() default SensitiveType.CUSTOMER;        int prefixNoMaskLen() default 0;        int suffixNoMaskLen() default 0;        String symbol() default "*";}
2.1 脱敏类型枚举 SensitiveType
public enum SensitiveType {        CUSTOMER,        CHINESE_NAME,        ID_CARD_NUM,        MOBILE_PHONE,        FIXED_PHONE,        PASSWord,        BANKCARD,        EMaiL,        ADDRESS,}
2.3 脱敏工具 DesensitizedUtils
import com.ruoyi.common.annotation.Sensitive;import com.ruoyi.common.constant.httpstatus;import com.ruoyi.common.core.domain.ajaxResult;import com.ruoyi.common.enums.SensitiveType;import lombok.extern.slf4j.Slf4j;import java.lang.reflect.Field;import java.util.*;@Slf4jpublic class DesensitizedUtils<T> {        private List<T> list;        private List<Object[]> fields;        public Class<T> clazz;    public DesensitizedUtils(Class<T> clazz)    {        this.clazz = clazz;    }        public void init(List<T> list){        if (list == null)        {            list = new ArrayList<T>();        }        this.list = list;        // 得到所有定义字段        createSensitiveField();    }        public void init(T t){        list = new ArrayList<T>();        if (t != null)        {         list.add(t);        }        // 得到所有定义字段        createSensitiveField();    }        private void createSensitiveField()    {        this.fields = new ArrayList<Object[]>();        List<Field> tempFields = new ArrayList<>();        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));        for (Field field : tempFields)        {            // 单注解            if (field.isAnnotationPresent(Sensitive.class))            {                putToField(field, field.getAnnotation(Sensitive.class));            }            // 多注解//            if (field.isAnnotationPresent(excels.class))//            {//                Excels attrs = field.getAnnotation(Excels.class);//                Excel[] excels = attrs.value();//                for (Excel excel : excels)//                {//                    putToField(field, excel);//                }//            }        }    }        public AjaxResult desensitizedList(List<T> list){        if (list == null){            return AjaxResult.error("脱敏数据为空");        }        // 初始化数据        this.init(list);        int failTimes = 0;        for (T t: this.list) {            if ((Integer)desensitization(t).get("code") != HttpStatus.SUCCESS){                failTimes++;            }        }        if (failTimes >0){            return AjaxResult.error("脱敏操作中出现失败",failTimes);        }        return AjaxResult.success();    }        private void putToField(Field field, Sensitive attr)    {        if (attr != null)        {            this.fields.add(new Object[] { field, attr });        }    }        public AjaxResult desensitization(T t) {        if (t == null){            return AjaxResult.error("脱敏数据为空");        }        // 初始化数据        init(t);        try {            // 遍历处理需要进行 脱敏的字段            for (Object[] os : fields)            {                Field field = (Field) os[0];                Sensitive sensitive = (Sensitive) os[1];                // 设置实体类私有属性可访问                field.setAccessible(true);                desensitizeField(sensitive,t,field);            }            return AjaxResult.success(t);        } catch (Exception e) {            e.printStackTrace();            log.error("日志脱敏处理失败,回滚,详细信息:[{}]", e);            return AjaxResult.error("脱敏处理失败",e);        }    }        private void desensitizeField(Sensitive attr, T vo, Field field) throws IllegalAccessException {        if (attr == null || vo == null || field == null){            return ;        }        // 读取对象中的属性        Object value = field.get(vo);        SensitiveType sensitiveType = attr.type();        int prefixNoMaskLen = attr.prefixNoMaskLen();        int suffixNoMaskLen = attr.suffixNoMaskLen();        String symbol = attr.symbol();        //获取属性后现在默认处理的是String类型,其他类型数据可扩展        Object val = convertByType(sensitiveType, value, prefixNoMaskLen, suffixNoMaskLen, symbol);        field.set(vo, val);    }        private Object getValue(Object o, String name) throws Exception    {        if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name))        {            Class<?> clazz = o.getClass();            Field field = clazz.getDeclaredField(name);            field.setAccessible(true);            o = field.get(o);        }        return o;    }        private Object convertByType(SensitiveType sensitiveType, Object value, int prefixNoMaskLen, int suffixNoMaskLen, String symbol) {        switch (sensitiveType) {            case CUSTOMER:                value = customer(value, prefixNoMaskLen, suffixNoMaskLen, symbol);                break;            case CHINESE_NAME:                value = chineseName(value, symbol);                break;            case ID_CARD_NUM:                value = idCardNum(value, symbol);                break;            case MOBILE_PHONE:                value = mobilePhone(value, symbol);                break;            case FIXED_PHONE:                value = fixedPhone(value, symbol);                break;            case PASSWORD:                value = password(value, symbol);                break;            case BANKCARD:                value = bankCard(value, symbol);                break;            case EMAIL:                value = email(value, symbol);                break;            case ADDRESS:                value = address(value, symbol);                break;        }        return value;    }            public Object customer(Object value, int prefixNoMaskLen, int suffixNoMaskLen, String symbol) {        //针对字符串的处理        if (value instanceof String){            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return value;    }        private String handleString(String s, int prefixNoMaskLen, int suffixNoMaskLen, String symbol){        // 是否为空        if (StringUtils.isBlank(s)) {            return "";        }        // 如果设置为空之类使用 * 代替        if (StringUtils.isBlank(symbol)){            symbol = "*";        }        // 对长度进行判断        int length = s.length();        if (length > prefixNoMaskLen + suffixNoMaskLen){            String namePrefix = StringUtils.left(s, prefixNoMaskLen);            String nameSuffix = StringUtils.right(s, suffixNoMaskLen);            s = StringUtils.rightPad(namePrefix, StringUtils.length(s) - suffixNoMaskLen, symbol).concat(nameSuffix);        }        return s;    }        public String chineseName(Object value, String symbol) {        //针对字符串的处理        if (value instanceof String){            // 对前后长度进行设置 默认 开头只展示一个字符            int prefixNoMaskLen = 1;            int suffixNoMaskLen = 0;            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return "";    }        public String idCardNum(Object value, String symbol) {        //针对字符串的处理        if (value instanceof String){            // 对前后长度进行设置 默认 结尾只展示四个字符            int prefixNoMaskLen = 0;            int suffixNoMaskLen = 4;            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return "";    }        public String fixedPhone(Object value, String symbol) {        //针对字符串的处理        if (value instanceof String){            // 对前后长度进行设置 默认 结尾只展示四个字符            int prefixNoMaskLen = 0;            int suffixNoMaskLen = 4;            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return "";    }        public String mobilePhone(Object value, String symbol) {        //针对字符串的处理        if (value instanceof String){            // 对前后长度进行设置 默认 开头只展示三个字符  结尾只展示四个字符            int prefixNoMaskLen = 3;            int suffixNoMaskLen = 4;            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return "";    }        public String address(Object value, String symbol) {        //针对字符串的处理        if (value instanceof String){            // 对前后长度进行设置 默认 开头只展示九个字符            int prefixNoMaskLen = 9;            int suffixNoMaskLen = 0;            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return "";    }        public String email(Object value, String symbol) {        //针对字符串的处理        if (value instanceof String){            // 对前后长度进行设置 默认 开头只展示一个字符  结尾只展示@及后面的地址            int prefixNoMaskLen = 1;            int suffixNoMaskLen = 4;            String s = (String) value;            if (StringUtils.isBlank(s)) {                return "";            }            // 获取最后一个@            int lastIndex = StringUtils.lastIndexOf(s, "@");            if (lastIndex <= 1) {                return s;            } else {                suffixNoMaskLen = s.length() - lastIndex;            }            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return "";    }        public String bankCard(Object value, String symbol) {        //针对字符串的处理        if (value instanceof String){            // 对前后长度进行设置 默认 开头只展示六个字符  结尾只展示四个字符            int prefixNoMaskLen = 6;            int suffixNoMaskLen = 4;            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return "";    }        public String password(Object value,String symbol) {        //针对字符串的处理        if (value instanceof String){            // 对前后长度进行设置 默认 开头只展示六个字符  结尾只展示四个字符            int prefixNoMaskLen = 0;            int suffixNoMaskLen = 0;            return handleString((String) value, prefixNoMaskLen, suffixNoMaskLen, symbol);        }        return "";    }}

3 使用实例

3.1 需注解对象
public class User {    private static final long serialVersionUID = 1L;        private Long userId;        @Sensitive(type = SensitiveType.CUSTOMER,prefixNoMaskLen = 2,suffixNoMaskLen = 1)    private String nickName;        @Sensitive(type = SensitiveType.CHINESE_NAME)    private String userName;        @Sensitive(type = SensitiveType.ID_CARD_NUM)    private String identityCard;        @Sensitive(type = SensitiveType.MOBILE_PHONE)    private String phoneNumber;}
3.2 脱敏操作
// 脱敏对象User user = new User();......        DesensitizedUtils<User> desensitizedUtils = new DesensitizedUtils<>(User.class);        desensitizedUtils.desensitization(user);//脱敏队列List<User> users = new ArrayList<>();......        DesensitizedUtils<User> desensitizedUtils = new DesensitizedUtils<>(User.class);        desensitizedUtils.desensitizedList(users);

以上就是关于“SpringBoot怎么新增脱敏功能”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

--结束END--

本文标题: SpringBoot怎么新增脱敏功能

本文链接: https://lsjlt.com/news/346525.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SpringBoot怎么新增脱敏功能
    这篇“SpringBoot怎么新增脱敏功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringBoot怎么新增脱敏功能...
    99+
    2023-07-04
  • SpringBoot怎么自定义注解实现涉密字段脱敏
    这篇文章主要讲解了“SpringBoot怎么自定义注解实现涉密字段脱敏”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot怎么自定义注解实现涉密字段脱敏”吧!关于数据脱敏,网上...
    99+
    2023-07-05
  • css3新增的功能是什么
    本篇内容介绍了“css3新增的功能是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • HTML5新增哪些功能
    本篇内容主要讲解“HTML5新增哪些功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HTML5新增哪些功能”吧!一、HTML5概念HTML5并不仅仅只是做为HTML标记语言的一个最新版本,更重...
    99+
    2023-06-05
  • Ubuntu One新更新增加了什么功能
    小编给大家分享一下Ubuntu One新更新增加了什么功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!据著名网站OMGUBUNTU消息,在Ubuntu11.04...
    99+
    2023-06-16
  • Go中新增的功能是什么
    这篇文章主要讲解了“Go中新增的功能是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go中新增的功能是什么”吧!什么是模糊测试?模糊测试fuzz testing(fuzzing)是指向你...
    99+
    2023-06-29
  • ADO.NET3.5新增了哪些功能
    本篇内容介绍了“ADO.NET3.5新增了哪些功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!ADO.NET3.5的新增重要方法:新增了L...
    99+
    2023-06-17
  • springboot vue测试平台前端项目查询新增功能
    目录基于 springboot+vue 的测试平台开发一、查询功能1. input 输入框2. 查询按钮二、新增功能1. 新增按钮2. 对话框3. 新增数据基于 springboot...
    99+
    2024-04-02
  • springboot vue测试平台接口定义前后端新增功能怎么实现
    这篇文章主要讲解了“springboot vue测试平台接口定义前后端新增功能怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“springboot vue测试平台接...
    99+
    2023-07-06
  • WordPress 2.8新增功能有哪些
    WordPress 2.8新增功能有哪些?WordPress 2.8的发布,为WordPress网站开发者带来了更多的便利,让像WPYOU这样的基于WordPress的开发服务商,在主题开发上有了更多的可操作和自定义功能,以下是WordPr...
    99+
    2018-01-24
    WordPress
  • NumPy新增的功能有哪些
    本篇内容主要讲解“NumPy新增的功能有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“NumPy新增的功能有哪些”吧!作为 Python 语言的一个扩展程序...
    99+
    2024-04-02
  • html5中新增功能有哪些
    这篇文章主要介绍了html5中新增功能有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。<!DOCTYPE html><html la...
    99+
    2023-06-09
  • Silverlight 4.0新增功能有哪些
    小编给大家分享一下Silverlight 4.0新增功能有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!Silverlight 4.0看来已经跃跃欲试了,尽管Silverlight3刚刚发布。从微软正式公布的新功能看,...
    99+
    2023-06-17
  • JDK15新增的功能有哪些
    本篇内容介绍了“JDK15新增的功能有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!发布版本说明根据发布的规划,这次发布的 JDK 15...
    99+
    2023-06-27
  • SpringBoot怎么整合Mybatis与thymleft实现增删改查功能
    这篇文章主要介绍“SpringBoot怎么整合Mybatis与thymleft实现增删改查功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot怎么整合Mybatis与thymlef...
    99+
    2023-07-04
  • Kali Linux中WPScan2.9.3增加了什么新功能
    这篇文章给大家分享的是有关Kali Linux中WPScan2.9.3增加了什么新功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Kali Linux WPScan更新到2.9.3WPScan是Kali Lin...
    99+
    2023-06-04
  • Java怎么用Jackson序列化实现数据脱敏
    这篇“Java怎么用Jackson序列化实现数据脱敏”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java怎么用Jackso...
    99+
    2023-07-05
  • HTML5新增加的功能有哪些
    这篇文章主要介绍了HTML5新增加的功能有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。HTML5现在已经不是SGML的子集,主要是增加...
    99+
    2024-04-02
  • Windows Server 2008 R2新增功能浅析
      对于桌面版Windows 7的消息我们已经听到了不少,最近的消息是微软表示将不再推出Windows 7的Beta版本,下一个升级版本将是最接近最终发布产品的RC版,这也意味着最终版离我们越来越近。不过根据微软企业级操...
    99+
    2023-05-24
    功能 浅析 新增 Windows Server R2 处理器 可以 支持 2008
  • WSH 5.6有哪些新增的功能
    这篇文章主要介绍“WSH 5.6有哪些新增的功能”,在日常操作中,相信很多人在WSH 5.6有哪些新增的功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”WSH 5.6有哪些新增的功能”的疑惑有所帮助!接下来...
    99+
    2023-06-08
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作