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

注解实现json序列化的时候自动进行数据脱敏

最近在进行开发的时候遇到一个问题,需要对用户信息进行脱敏处理,原有的方式是写一个util类,在需要脱敏的字段查出数据后,显示掉用方法处理后再set回去,觉得这种方式能实现功能,但是不是特别优雅,想找个比较优雅的实现 思考了一下,觉得数据只有在输出的时候进行脱敏处理即可,其它都是在内存阶段,相对来说都是比较安全的,输出阶段我想到了json序列化,因为我们用的restful接口输出json,于是去查询了一下相关的资源,jackson可以指定某个字段的自定义序列化类,那么还有一个问题,我指定了用某个类进行序列化,但是在序列化的时候如果判断脱敏的类型呢,翻看网上大神的文章得知,ContextualSerializer是 Jackson 提供的另一个序列化相关的接口,它的作用是通过字段已知的上下文信息定制JsonSerializer,只需要实现createContextual方法即可。废话少说,下面上代码:

用户信息实体:

@Data
public class UserDetailResponse {private Long useId;@ApiModelProperty(value = "用户编号")private String useNo;@ApiModelProperty(value = "用户姓名")private String useName;@SensitiveInfo(SensitiveType.MOBILE_PHONE)@ApiModelProperty(value = "用户手机号")private String mobile;@ApiModelProperty(value = "用户性别")private String sex;@ApiModelProperty(value = "用户年龄")private int age;@ApiModelProperty(value = "用户籍贯")private String nativePlace;@SensitiveInfo(SensitiveType.ID_CARD)@ApiModelProperty(value = "用户身份证号")private String idCard;@ApiModelProperty(value = "用户身份证号")private String borrowingLevel;
}

脱敏类型枚举类

public enum SensitiveType {/*** 中文名*/CHINESE_NAME,/*** 身份证号*/ID_CARD,/*** 座机号*/FIXED_PHONE,/*** 手机号*/MOBILE_PHONE,/*** 地址*/ADDRESS,/*** 电子邮件*/EMAIL,/*** 银行卡*/BANK_CARD,/*** 公司开户银行联号*/CNAPS_CODE
}


脱敏注解类

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveInfoSerialize.class)
public @interface SensitiveInfo {public SensitiveType value();
}

脱敏序列化类

public class SensitiveInfoSerialize extends JsonSerializer<String> implementsContextualSerializer {private SensitiveType type;public SensitiveInfoSerialize() {}public SensitiveInfoSerialize(final SensitiveType type) {this.type = type;}@Overridepublic void serialize(final String s, final JsonGenerator jsonGenerator,final SerializerProvider serializerProvider) throws IOException, JsonProcessingException {switch (this.type) {case CHINESE_NAME: {jsonGenerator.writeString(SensitiveInfoUtils.chineseName(s));break;}case ID_CARD: {jsonGenerator.writeString(SensitiveInfoUtils.idCardNum(s));break;}case FIXED_PHONE: {jsonGenerator.writeString(SensitiveInfoUtils.fixedPhone(s));break;}case MOBILE_PHONE: {jsonGenerator.writeString(SensitiveInfoUtils.mobilePhone(s));break;}case ADDRESS: {jsonGenerator.writeString(SensitiveInfoUtils.address(s, 4));break;}case EMAIL: {jsonGenerator.writeString(SensitiveInfoUtils.email(s));break;}case BANK_CARD: {jsonGenerator.writeString(SensitiveInfoUtils.bankCard(s));break;}case CNAPS_CODE: {jsonGenerator.writeString(SensitiveInfoUtils.cnapsCode(s));break;}}}@Overridepublic JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,final BeanProperty beanProperty) throws JsonMappingException {if (beanProperty != null) { // 为空直接跳过if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) { // 非 String 类直接跳过SensitiveInfo sensitiveInfo = beanProperty.getAnnotation(SensitiveInfo.class);if (sensitiveInfo == null) {sensitiveInfo = beanProperty.getContextAnnotation(SensitiveInfo.class);}if (sensitiveInfo != null) { // 如果能得到注解,就将注解的 value 传入 SensitiveInfoSerializereturn new SensitiveInfoSerialize(sensitiveInfo.value());}}return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);}return serializerProvider.findNullValueSerializer(beanProperty);}
}


脱敏处理util类


public class SensitiveInfoUtils {/*** [中文姓名] 只显示第一个汉字,其他隐藏为2个星号<例子:李**>*/public static String chineseName(final String fullName) {if (StringUtils.isBlank(fullName)) {return "";}final String name = StringUtils.left(fullName, 1);return StringUtils.rightPad(name, StringUtils.length(fullName), "*");}/*** [中文姓名] 只显示第一个汉字,其他隐藏为2个星号<例子:李**>*/public static String chineseName(final String familyName, final String givenName) {if (StringUtils.isBlank(familyName) || StringUtils.isBlank(givenName)) {return "";}return chineseName(familyName + givenName);}/*** [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。<例子:*************5762>*/public static String idCardNum(final String id) {if (StringUtils.isBlank(id)) {return "";}return StringUtils.left(id, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(id, 3), StringUtils.length(id), "*"),"***"));}/*** [固定电话] 后四位,其他隐藏<例子:****1234>*/public static String fixedPhone(final String num) {if (StringUtils.isBlank(num)) {return "";}return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");}/*** [手机号码] 前三位,后四位,其他隐藏<例子:138******1234>*/public static String mobilePhone(final String num) {if (StringUtils.isBlank(num)) {return "";}return StringUtils.left(num, 2).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(num, 2), StringUtils.length(num), "*"),"***"));}/*** [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护<例子:北京市海淀区****>** @param sensitiveSize 敏感信息长度*/public static String address(final String address, final int sensitiveSize) {if (StringUtils.isBlank(address)) {return "";}final int length = StringUtils.length(address);return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*");}/*** [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示<例子:g**@163.com>*/public static String email(final String email) {if (StringUtils.isBlank(email)) {return "";}final int index = StringUtils.indexOf(email, "@");if (index <= 1) {return email;} else {return StringUtils.rightPad(StringUtils.left(email, 1), index, "*").concat(StringUtils.mid(email, index, StringUtils.length(email)));}}/*** [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号<例子:6222600**********1234>*/public static String bankCard(final String cardNum) {if (StringUtils.isBlank(cardNum)) {return "";}return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"),"******"));}/*** [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号<例子:12********>*/public static String cnapsCode(final String code) {if (StringUtils.isBlank(code)) {return "";}return StringUtils.rightPad(StringUtils.left(code, 2), StringUtils.length(code), "*");}}


效果图:


此文主要参考了下面几位大神的文章

http://www.scienjus.com/get-field-annotation-property-by-jackson-contextualserializer/

http://blog.csdn.net/liuc0317/article/details/48787793

http://www.voidcn.com/article/p-ezjgnfeh-bee.html

相关文章:

注解实现json序列化的时候自动进行数据脱敏

最近在进行开发的时候遇到一个问题&#xff0c;需要对用户信息进行脱敏处理&#xff0c;原有的方式是写一个util类&#xff0c;在需要脱敏的字段查出数据后&#xff0c;显示掉用方法处理后再set回去&#xff0c;觉得这种方式能实现功能&#xff0c;但是不是特别优雅&#xff0c…...

使用Python下载文件的简易指南

在日常的数据处理、自动化任务或软件开发中&#xff0c;经常需要从网络上下载文件。Python作为一门功能强大的编程语言&#xff0c;提供了多种方法来实现文件的下载。本文将介绍几种常用的方法来使用Python下载文件&#xff0c;包括使用requests库和urllib库。 准备工作 在开…...

中秋国庆双节长假,景区迎来客流高峰,如何保障景区安全管理?

一、方案背景 近年来&#xff0c;国内旅游市场持续升温&#xff0c;节假日期间景区游客数量激增&#xff0c;给景区安全管理带来了巨大挑战。然而&#xff0c;景区安全风险意识不足、防护措施不完善、游客安全意识欠缺等问题依然存在&#xff0c;导致景区安全事故频发。随着中秋…...

多维数组转一维数组:探索 JavaScript 中的数组扁平化

在 JavaScript 编程中&#xff0c;我们经常会遇到需要将多维数组转换为一维数组的情况。无论是处理复杂的数据结构还是进行数据的进一步操作&#xff0c;数组扁平化都是一个常见且有用的技术。本文将介绍几种在 JavaScript 中将多维数组转换为一维数组的方法。 什么是数组扁平…...

配环境时的一些记录

连centos&#xff1a;正常连就好&#xff08;密码验证码&#xff09;连rocky&#xff1a;需要在centos上连&#xff0c;终端里直接ssh [rocky_ip]&#xff1b;在vscode中需要&#xff1a; 修改配置文件&#xff1a;打开命令面板&#xff08;ctrlshiftp&#xff09; -> 输入并…...

如何解析域名到网站?

在现代互联网中&#xff0c;域名解析是用户访问网站的关键过程。用户通过输入易于记忆的域名来访问网站&#xff0c;而背后则是复杂的域名解析机制将域名转换为服务器的IP地址&#xff0c;使得浏览器能够找到并加载目标网站。聚名网详细介绍域名解析的过程及其相关技术。 一、…...

【F172】基于Springboot+vue实现的智能菜谱系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 项目描述 近些年&#xff0c;随着中国经济发展&#xff0c;人民的…...

Spring-AOP核心源码、原理详解前篇

本文主要分4部分 Aop原理介绍介绍aop相关的一些类通过源码详解aop代理的创建过程通过源码详解aop代理的调用过程Aop代理一些特性的使用案例 Spring AOP原理 原理比较简单&#xff0c;主要就是使用jdk动态代理和cglib代理来创建代理对象&#xff0c;通过代理对象来访问目标对象…...

Reflection反射——Class类

概述 在Java中&#xff0c;除了int等基本类型外&#xff0c;Java的其他类型全部都是class&#xff08;包括interface&#xff09;。例如&#xff1a; String、Object、Runnable、Exception…… Java反射机制是Java语言的一个重要特性。在学习Java反射机制前&#xff0c;需要了…...

王朝兴替的因果

天道好轮 回&#xff0c;苍天饶过谁。王朝兴亡&#xff0c;天道无情。 而其因果循环&#xff0c;天道之森严&#xff0c;让人敬畏。 王朝创业帝王造下什么业&#xff0c;后世子孙在兴替之时&#xff0c;往往要承担何种果 报。 中国几千年的王朝史&#xff0c;因 果循环&…...

损坏SD数据恢复的8种有效方法

SD卡被用于许多不同的产品来存储重要数据&#xff0c;如图片和重要的商业文件。如果您的SD卡坏了&#xff0c;您需要SD数据恢复来获取您的信息。通过从损坏的SD卡中取回数据&#xff0c;您可以确保重要文件不会永远丢失&#xff0c;这对于工作或个人原因是非常重要的。 有许多…...

好评如潮的年度黑马韩剧,惊喜从一上线就开始

韩剧一直以来都以细腻的情感和紧凑的剧情打动观众&#xff0c;而最近播出的一部作品更是掀起了不小的风波-《法官大人》。孙贤周与金明民两大演技派领衔主演&#xff0c;凭借他们的深沉演技和复杂的角色关系&#xff0c;让这部剧集迅速成为热议焦点。故事围绕着一起交通事故展开…...

超好用的PC端语音转文字工具CapsWriter-Offline结合内网穿透实现远程使用

文章目录 前言1. 软件与模型下载2. 本地使用测试3. 异地远程使用3.1 内网穿透工具下载安装3.2 配置公网地址3.3 修改config文件3.4 异地远程访问服务端 4. 配置固定公网地址4.1 修改config文件 5. 固定tcp公网地址远程访问服务端 前言 本文主要介绍如何在Windows系统电脑端使用…...

1、https的全过程

目录 一、概述二、SSL过程如何获取会话秘钥1、首先认识几个概念&#xff1a;2、没有CA机构的SSL过程&#xff1a;3、没有CA机构下的安全问题4、有CA机构下的SSL过程 一、概述 https是非对称加密和对称加密的过程&#xff0c;首先建立https链接需要经过两轮握手&#xff1a; T…...

抢鲜体验 PolarDB PG 15 开源版

unsetunsetPolarDB 商业版unsetunset 8 月&#xff0c;PolarDB PostgreSQL 版兼容 PostgreSQL 15 版本&#xff08;商业版&#xff09;正式发布上线。 当前版本主要增强优化了以下方面&#xff1a; 改进排序功能&#xff1a;改进内存和磁盘排序算法。 增强SQL功能&#xff1a;支…...

UEFI——使用标准C库

一、C标准库 C标准库是ANSL C标准为C语言定义的标准库。C标准库包含15个头文件&#xff1a;assert.h ctype.h error.h float.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stddef.h stdio.h stdlib.h string.h time.h。标准库函数与C语言的紧密结合给我们开发程序带…...

[全网首发]怎么让国行版iPhone使用苹果Apple Intelligence

全文共分为两个部分&#xff1a;第一让苹果手机接入AI&#xff0c;第二是让苹果手机接入ChatGPT 4o功能。 一、国行版iPhone开通 Apple Intelligence教程 打破限制&#xff1a;让国行版苹果手机也能接入AI 此次发布会上&#xff0c;虽然国行 iPhone16 系列不支持 GPT-4o&…...

C语言-综合案例:通讯录

传送门&#xff1a;C语言-第九章-加餐&#xff1a;文件位置指示器与二进制读写 目录 第一节&#xff1a;思路整理 第二节&#xff1a;代码编写 2-1.通讯录初始化 2-2.功能选择 2-3.增加 和 扩容 2-4.查看 2-5.查找 2-6.删除 2-7.修改 2-8.退出 第三节&#xff1a;测试 下期…...

XWiki中添加 html 二次编辑失效

如果直接在 XWiki 中添加 html, 例如 修改颜色, 新窗口打开主页面等功能, 首次保存是生效的. 如果再次编辑, 则失效, 原因是被转换成了 Markdown 的代码, 而 Markdown 不支持. 解决这个问题可以使用 HTML 宏. 在 XWiki 中使用 Markdown 1.2 语法时&#xff0c;默认 Markdown …...

外贸|基于Java+vue的智慧外贸平台系统(源码+数据库+文档)

外贸|智慧外贸平台|外贸服务系统 目录 基于Javavue的智慧外贸平台系统 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&…...

面试官:什么是最左前缀匹配?为什么要遵守?(修订版)

在线 Java 面试刷题&#xff08;持续更新&#xff09;&#xff1a;https://www.quanxiaoha.com/java-interview面试考察点原理理解&#xff1a;面试官不仅仅想知道你会背 "最左前缀原则"&#xff0c;更想考察你是否理解联合索引的 B 树存储结构&#xff0c;能否从数据…...

Phi-3 Forest Laboratory 数学公式处理:集成MathType逻辑的LaTeX代码生成

Phi-3 Forest Laboratory 数学公式处理&#xff1a;集成MathType逻辑的LaTeX代码生成 你是不是也遇到过这样的场景&#xff1f;写论文或者做笔记时&#xff0c;需要插入一个复杂的数学公式&#xff0c;比如那个让人头疼的“二元二次方程的求根公式”。你打开LaTeX编辑器&#…...

ssm+java2026年毕设随心淘网管理系统【源码+论文】

本系统&#xff08;程序源码&#xff09;带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、选题背景关于电商会员管理系统的研究&#xff0c;现有研究主要以大型综合电商平台&#xff08;如淘宝、京东&#xff09;的整体架构设计…...

大麦抢票自动化:用Python脚本突破手速限制的实战指南

大麦抢票自动化&#xff1a;用Python脚本突破手速限制的实战指南 【免费下载链接】DamaiHelper 大麦网演唱会演出抢票脚本。 项目地址: https://gitcode.com/gh_mirrors/dama/DamaiHelper 抢票困境与技术破局 每到热门演出开票时刻&#xff0c;无数粉丝都会陷入相同的困…...

终极指南:掌握AMD Ryzen SMU调试工具,解锁硬件调优新境界

终极指南&#xff1a;掌握AMD Ryzen SMU调试工具&#xff0c;解锁硬件调优新境界 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地…...

AudioSeal效果展示:对抗白噪声、混响、变速变调攻击的鲁棒性案例

AudioSeal效果展示&#xff1a;对抗白噪声、混响、变速变调攻击的鲁棒性案例 1. 音频水印技术新标杆 想象一下&#xff0c;当你听到一段AI生成的语音时&#xff0c;如何确认它的真实来源&#xff1f;这就是AudioSeal要解决的核心问题。作为Meta开源的语音水印系统&#xff0c…...

Z-Image-Turbo-rinaiqiao-huiyewunv 保姆级部署:Ubuntu系统环境配置与模型启动

Z-Image-Turbo-rinaiqiao-huiyewunv 保姆级部署&#xff1a;Ubuntu系统环境配置与模型启动 你是不是刚拿到一个功能强大的AI图像生成镜像&#xff0c;比如这个Z-Image-Turbo-rinaiqiao-huiyewunv&#xff0c;看着名字挺酷&#xff0c;但一想到要在Ubuntu服务器上部署&#xff…...

TlbbGmTool高效管理全流程实战指南:从部署到进阶的完整解决方案

TlbbGmTool高效管理全流程实战指南&#xff1a;从部署到进阶的完整解决方案 【免费下载链接】TlbbGmTool 某网络游戏的单机版本GM工具 项目地址: https://gitcode.com/gh_mirrors/tl/TlbbGmTool 在《天龙八部》游戏服务器管理中&#xff0c;管理员常常面临账号管理繁琐、…...

Win11Debloat:3步让你的Windows 11系统重获新生

Win11Debloat&#xff1a;3步让你的Windows 11系统重获新生 【免费下载链接】Win11Debloat 一个简单的PowerShell脚本&#xff0c;用于从Windows中移除预装的无用软件&#xff0c;禁用遥测&#xff0c;从Windows搜索中移除Bing&#xff0c;以及执行各种其他更改以简化和改善你的…...

别再只用ChatGPT了!用JavaScript的Web Speech API给你的网页加个‘嘴’(附完整代码)

用Web Speech API给你的网页装个"智能语音助手"&#xff1a;从基础到实战 当我们在讨论网页交互创新时&#xff0c;大多数人会立刻想到复杂的AI对话系统。但你可能不知道&#xff0c;浏览器原生就内置了一个被严重低估的语音合成神器——Web Speech API。想象一下&am…...