本文目录导读:

我来为您提供一个完整的Java数据脱敏实现方案,包含多种脱敏策略和实际应用案例。
脱敏工具类实现
import java.util.regex.Pattern;
/**
* 数据脱敏工具类
*/
public class DesensitizedUtil {
/**
* 手机号脱敏:保留前3位和后4位
*/
public static String mobilePhone(String mobile) {
if (isEmpty(mobile)) {
return "";
}
return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
}
/**
* 身份证号脱敏:保留前6位和后4位
*/
public static String idCard(String idCard) {
if (isEmpty(idCard)) {
return "";
}
return idCard.replaceAll("(\\d{6})\\d{8}(\\d{4})", "$1********$2");
}
/**
* 银行卡号脱敏:保留前4位和后4位
*/
public static String bankCard(String cardNo) {
if (isEmpty(cardNo)) {
return "";
}
return cardNo.replaceAll("(\\d{4})\\d{8,12}(\\d{4})", "$1********$2");
}
/**
* 姓名脱敏:保留姓氏,名字用*代替
*/
public static String chineseName(String name) {
if (isEmpty(name)) {
return "";
}
if (name.length() == 1) {
return "*";
}
return name.replaceAll("(.)(.*)", "$1" + repeat("*", name.length() - 1));
}
/**
* 邮箱脱敏:保留第一个字母和@后面部分
*/
public static String email(String email) {
if (isEmpty(email)) {
return "";
}
int index = email.indexOf("@");
if (index <= 1) {
return email;
}
return email.substring(0, 1) + "***" + email.substring(index);
}
/**
* 地址脱敏:保留前6个字符
*/
public static String address(String address) {
if (isEmpty(address)) {
return "";
}
if (address.length() <= 6) {
return address;
}
return address.substring(0, 6) + "******";
}
/**
* 密码脱敏:全部替换为*
*/
public static String password(String password) {
if (isEmpty(password)) {
return "";
}
return repeat("*", password.length());
}
/**
* 自定义脱敏
*/
public static String custom(String str, int front, int end) {
if (isEmpty(str)) {
return "";
}
if (str.length() <= front + end) {
return str;
}
return str.substring(0, front) + repeat("*", str.length() - front - end) + str.substring(str.length() - end);
}
private static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
private static String repeat(String str, int count) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append(str);
}
return sb.toString();
}
}
基于注解的脱敏方案
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 脱敏注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveField {
SensitiveType type() default SensitiveType.CUSTOM;
int front() default 2; // 保留前几位
int end() default 2; // 保留后几位
}
/**
* 脱敏类型枚举
*/
public enum SensitiveType {
MOBILE_PHONE, // 手机号
ID_CARD, // 身份证
BANK_CARD, // 银行卡
NAME, // 姓名
EMAIL, // 邮箱
ADDRESS, // 地址
PASSWORD, // 密码
CUSTOM // 自定义
}
脱敏处理器
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* 脱敏处理器
*/
public class SensitiveDataProcessor {
/**
* 处理单个对象
*/
public static <T> T process(T object) {
if (object == null) {
return null;
}
try {
Class<?> clazz = object.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(SensitiveField.class)) {
field.setAccessible(true);
Object value = field.get(object);
if (value instanceof String) {
SensitiveField annotation = field.getAnnotation(SensitiveField.class);
String result = desensitize((String) value, annotation);
field.set(object, result);
}
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return object;
}
/**
* 处理对象列表
*/
public static <T> List<T> processList(List<T> list) {
if (list == null || list.isEmpty()) {
return list;
}
List<T> result = new ArrayList<>();
for (T item : list) {
result.add(process(item));
}
return result;
}
/**
* 执行脱敏
*/
private static String desensitize(String value, SensitiveField annotation) {
if (value == null || value.isEmpty()) {
return value;
}
switch (annotation.type()) {
case MOBILE_PHONE:
return DesensitizedUtil.mobilePhone(value);
case ID_CARD:
return DesensitizedUtil.idCard(value);
case BANK_CARD:
return DesensitizedUtil.bankCard(value);
case NAME:
return DesensitizedUtil.chineseName(value);
case EMAIL:
return DesensitizedUtil.email(value);
case ADDRESS:
return DesensitizedUtil.address(value);
case PASSWORD:
return DesensitizedUtil.password(value);
case CUSTOM:
return DesensitizedUtil.custom(value, annotation.front(), annotation.end());
default:
return value;
}
}
}
实体类示例
/**
* 用户实体类
*/
public class User {
private Long id;
@SensitiveField(type = SensitiveType.NAME)
private String name;
@SensitiveField(type = SensitiveType.MOBILE_PHONE)
private String phone;
@SensitiveField(type = SensitiveType.ID_CARD)
private String idCard;
@SensitiveField(type = SensitiveType.EMAIL)
private String email;
@SensitiveField(type = SensitiveType.PASSWORD)
private String password;
@SensitiveField(type = SensitiveType.ADDRESS)
private String address;
@SensitiveField(type = SensitiveType.BANK_CARD)
private String bankCard;
@SensitiveField(type = SensitiveType.CUSTOM, front = 2, end = 2)
private String customField;
// getters and setters
// ...
}
实际应用示例
import com.alibaba.fastjson2.JSON;
import java.util.Arrays;
import java.util.List;
/**
* 脱敏使用示例
*/
public class DesensitizationDemo {
public static void main(String[] args) {
// 创建测试数据
User user = new User();
user.setId(1L);
user.setName("张三");
user.setPhone("13812345678");
user.setIdCard("110101199003071234");
user.setEmail("zhangsan@example.com");
user.setPassword("password123");
user.setAddress("北京市海淀区中关村大街1号");
user.setBankCard("6222020302012345678");
user.setCustomField("自定义字段测试");
// 单个对象脱敏
System.out.println("=== 单个对象脱敏 ===");
User processed = SensitiveDataProcessor.process(user);
System.out.println(JSON.toJSONString(processed, true));
// 列表脱敏
System.out.println("=== 列表脱敏 ===");
List<User> userList = Arrays.asList(user, user);
List<User> processedList = SensitiveDataProcessor.processList(userList);
System.out.println(JSON.toJSONString(processedList));
// 直接使用工具类脱敏
System.out.println("=== 工具类直接调用 ===");
System.out.println("手机号: " + DesensitizedUtil.mobilePhone("13812345678"));
System.out.println("身份证: " + DesensitizedUtil.idCard("110101199003071234"));
System.out.println("姓名: " + DesensitizedUtil.chineseName("张三丰"));
System.out.println("邮箱: " + DesensitizedUtil.email("zhangsan@example.com"));
System.out.println("银行卡: " + DesensitizedUtil.bankCard("6222020302012345678"));
System.out.println("地址: " + DesensitizedUtil.address("北京市海淀区中关村大街1号"));
System.out.println("密码: " + DesensitizedUtil.password("123456"));
System.out.println("自定义: " + DesensitizedUtil.custom("123456789", 2, 3));
}
}
使用AOP实现自动脱敏
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
/**
* 自动脱敏切面
*/
@Aspect
@Component
public class SensitiveDataAspect {
/**
* 拦截Controller层的返回结果进行脱敏
*/
@Around("@annotation(com.example.annotation.NoSensitive) || within(com.example.controller.*)")
public Object processData(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
if (result == null) {
return null;
}
// 处理单个对象
if (!(result instanceof Iterable) && !(result instanceof org.springframework.http.ResponseEntity)) {
return SensitiveDataProcessor.process(result);
}
// 处理列表
if (result instanceof List) {
return SensitiveDataProcessor.processList((List<?>) result);
}
return result;
}
}
配置脱敏规则
import java.util.HashMap;
import java.util.Map;
/**
* 脱敏规则配置
*/
public class SensitiveRuleConfig {
private static final Map<String, SensitiveType> RULE_MAP = new HashMap<>();
static {
RULE_MAP.put("userName", SensitiveType.NAME);
RULE_MAP.put("mobile", SensitiveType.MOBILE_PHONE);
RULE_MAP.put("idCard", SensitiveType.ID_CARD);
RULE_MAP.put("email", SensitiveType.EMAIL);
RULE_MAP.put("password", SensitiveType.PASSWORD);
RULE_MAP.put("address", SensitiveType.ADDRESS);
RULE_MAP.put("bankCard", SensitiveType.BANK_CARD);
}
/**
* 根据字段名获取脱敏策略
*/
public static SensitiveType getType(String fieldName) {
return RULE_MAP.getOrDefault(fieldName, SensitiveType.CUSTOM);
}
}
/**
* 动态脱敏处理
*/
public class DynamicDesensitizedProcessor {
/**
* 处理Map类型的参数
*/
public static Map<String, Object> processMap(Map<String, Object> data) {
if (data == null || data.isEmpty()) {
return data;
}
Map<String, Object> result = new HashMap<>();
for (Map.Entry<String, Object> entry : data.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String) {
SensitiveType type = SensitiveRuleConfig.getType(key);
switch (type) {
case NAME:
result.put(key, DesensitizedUtil.chineseName((String) value));
break;
case MOBILE_PHONE:
result.put(key, DesensitizedUtil.mobilePhone((String) value));
break;
case ID_CARD:
result.put(key, DesensitizedUtil.idCard((String) value));
break;
case EMAIL:
result.put(key, DesensitizedUtil.email((String) value));
break;
case PASSWORD:
result.put(key, DesensitizedUtil.password((String) value));
break;
case ADDRESS:
result.put(key, DesensitizedUtil.address((String) value));
break;
case BANK_CARD:
result.put(key, DesensitizedUtil.bankCard((String) value));
break;
default:
result.put(key, value);
}
} else {
result.put(key, value);
}
}
return result;
}
}
测试类
import java.util.HashMap;
import java.util.Map;
/**
* 测试类
*/
public class DesensitizedTest {
public static void main(String[] args) {
// 测试各种脱敏情况
System.out.println("=== 边界测试 ===");
System.out.println("空字符串: '" + DesensitizedUtil.mobilePhone("") + "'");
System.out.println("null值: '" + DesensitizedUtil.mobilePhone(null) + "'");
System.out.println("短字符串: " + DesensitizedUtil.chineseName("刘"));
System.out.println("英文名: " + DesensitizedUtil.chineseName("John"));
// 测试Map处理
System.out.println("=== Map数据脱敏 ===");
Map<String, Object> userData = new HashMap<>();
userData.put("userName", "张三");
userData.put("mobile", "13812345678");
userData.put("idCard", "110101199003071234");
userData.put("email", "zhangsan@example.com");
userData.put("password", "abc123");
Map<String, Object> processedData = DynamicDesensitizedProcessor.processMap(userData);
processedData.forEach((key, value) -> System.out.println(key + ": " + value));
}
}
这个案例提供了完整的Java数据脱敏解决方案,包括:
- 多种脱敏策略:手机号、身份证、银行卡、姓名、邮箱、地址、密码等
- 注解方式:通过
@SensitiveField注解实现字段级脱敏 - 自动处理:使用AOP实现返回值自动脱敏
- 动态配置:支持配置化的脱敏规则
- 实用工具:提供独立的工具类方法供直接调用
使用方式灵活,可以根据实际需求选择适合的脱敏方式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播