对外提供数据脱敏需“该露的露、该藏的藏”,按字段类型定制规则(如手机号、身份证号、邮箱、银行卡号),结合jackson注解实现序列化自动脱敏,并封装可开关的工具类,兼顾合规、安全与业务可读性。

对外提供数据时做脱敏,核心是“该露的露、该藏的藏”,不破坏数据结构和业务可读性,同时满足合规与安全要求。重点不是把数据全加密或删掉,而是让敏感字段在展示、日志、接口返回等环节只保留必要信息。
按字段类型定制脱敏规则
不同字段脱敏逻辑差异大,硬套一个方法容易出错。建议为每类敏感字段单独封装处理逻辑:
-
手机号:保留前3位和后4位,中间4位用*替换,如
139****5678;注意校验长度是否为11位,避免对空值或异常格式直接操作 -
身份证号:保留前6位(地区码)和后4位(校验码+生日尾数),中间8位隐藏,如
110101********1234;需兼容15位旧证(可先统一转18位再处理) -
邮箱:保留首字母和@后域名,中间用*遮盖,如
e***@gmail.com;注意区分大小写和特殊符号(如user+tag@domain中的+) -
银行卡号:通常保留前6位(BIN号)和后4位,中间分段用空格+*表示,如
6222 **** **** 8888;避免直接截取,应按4位一组处理
在序列化阶段自动脱敏
避免在每个Controller里手动调用脱敏工具,推荐结合Jackson做注解驱动脱敏:
- 自定义
@Desensitize注解,标注在DTO字段上,指定脱敏类型(如PHONE、ID_CARD) - 实现
JsonSerializer<string></string>,根据注解类型动态执行对应脱敏逻辑 - 在
@JsonSerialize中引用该序列化器,或全局注册为默认String处理器 - 这样只要对象被Jackson转JSON,敏感字段就自动脱敏,不影响原有业务代码
统一脱敏工具类 + 可配置开关
封装一个轻量级工具类,支持运行时开关控制脱敏行为:
- 提供
DesensitizationUtils.mask(String value, DesensitizeType type)方法,入参明确、语义清晰 - 内部用正则预编译(如
Pattern.compile("(\d{3})\d{4}(\d{4})")),提升高频调用性能 - 增加环境判断开关,例如开发/测试环境强制脱敏,生产环境可根据配置项开启或关闭(便于排查问题)
- 对null、空字符串、超长/非法格式做防御性处理,返回原值或空字符串,不抛异常
避免常见坑点
脱敏看似简单,实际容易踩雷:
- 日志中打印对象时,如果用了
toString()或Lombok的@Data,可能把原始敏感字段打出来——建议重写toString()或用@ToString.Exclude - 数据库查询结果直接转Map再返回,没走DTO层,脱敏逻辑失效——统一收口到DTO构建阶段
- 前端传来的脱敏数据(如
139****5678)又被后端当原始号码去查库——需明确区分“输入校验”和“输出展示”场景 - 加密后存储的数据,不能用脱敏逻辑再处理——脱敏只适用于明文展示,加密/哈希属于另一层安全机制
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











