本文目录导读:

我来详细说明Java分布式数据脱敏API的实现方案:
整体架构设计
架构组件图
客户端 (SDK/API)
↓
API网关层 (路由、限流、鉴权)
↓
脱敏服务层 (核心处理)
├── 规则引擎
├── 脱敏处理器
└── 缓存管理
↓
存储层 (Redis/数据库)
核心接口定义
public interface DesensitizationService {
// 单字段脱敏
String desensitize(String originalValue, DesensitizeType type);
// 批量脱敏
Map<String, String> batchDesensitize(Map<String, String> dataMap);
// 结构化数据脱敏
<T> T desensitizeObject(T object, Class<T> clazz);
// 自定义规则脱敏
String desensitizeWithRule(String value, String ruleName);
}
public enum DesensitizeType {
PHONE, // 手机号 138****1234
ID_CARD, // 身份证 110***********1234
EMAIL, // 邮箱 t**@example.com
BANK_CARD, // 银行卡号 6222****1234
NAME, // 姓名 张**
ADDRESS, // 地址 ****街道
CUSTOM // 自定义
}
核心实现代码
脱敏处理器接口及实现
// 脱敏处理器接口
public interface DesensitizeHandler {
String handle(String value, Map<String, String> params);
DesensitizeType getType();
}
// 手机号脱敏
@Component
public class PhoneDesensitizeHandler implements DesensitizeHandler {
@Override
public String handle(String value, Map<String, String> params) {
if (StringUtils.isBlank(value)) {
return value;
}
int prefixLength = params.getOrDefault("prefixLength", "3")
.equals("3") ? 3 : 2;
int suffixLength = params.getOrDefault("suffixLength", "4")
.equals("4") ? 4 : 3;
StringBuilder sb = new StringBuilder(value);
for (int i = prefixLength; i < value.length() - suffixLength; i++) {
sb.setCharAt(i, '*');
}
return sb.toString();
}
@Override
public DesensitizeType getType() {
return DesensitizeType.PHONE;
}
}
// 身份证脱敏
@Component
public class IdCardDesensitizeHandler implements DesensitizeHandler {
@Override
public String handle(String value, Map<String, String> params) {
if (StringUtils.isBlank(value) || value.length() < 15) {
return value;
}
// 保留前6位后4位
String prefix = value.substring(0, 6);
String suffix = value.substring(value.length() - 4);
String middle = StringUtils.repeat("*", value.length() - 10);
return prefix + middle + suffix;
}
@Override
public DesensitizeType getType() {
return DesensitizeType.ID_CARD;
}
}
规则引擎实现
@Component
public class DesensitizeRuleEngine {
// 规则缓存 - 支持动态更新
private final Map<String, DesensitizeRule> ruleCache = new ConcurrentHashMap<>();
// 规则定义
@Data
public static class DesensitizeRule {
private String ruleName;
private DesensitizeType type;
private String pattern; // 正则表达式,如:(\d{3})\d{4}(\d{4})
private String replacement; // 替换内容,如:$1****$2
private Map<String, String> params; // 参数配置
// 是否启用
private boolean enabled = true;
}
// 根据规则执行脱敏
public String execute(String value, DesensitizeRule rule) {
if (!rule.isEnabled() || StringUtils.isBlank(value)) {
return value;
}
// 1. 正则替换
if (StringUtils.isNotBlank(rule.getPattern())) {
value = value.replaceAll(rule.getPattern(), rule.getReplacement());
}
// 2. 调用对应的处理器
DesensitizeHandler handler = handlerFactory.getHandler(rule.getType());
if (handler != null) {
value = handler.handle(value, rule.getParams());
}
return value;
}
// 动态更新规则 - 支持运行时变更
public void updateRule(DesensitizeRule rule) {
String key = buildRuleKey(rule.getRuleName(), rule.getType());
ruleCache.put(key, rule);
// 发布配置变更事件,通知其他节点
publishConfigChangeEvent(rule);
}
}
分布式缓存支持
@Component
public class DistributedCacheManager {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final String CACHE_PREFIX = "desensitize:rule:";
private static final long CACHE_TTL = 3600; // 1小时
// 缓存脱敏结果
public String getCachedDesensitizedValue(String original, DesensitizeType type) {
String cacheKey = buildCacheKey(original, type);
String cachedValue = (String) redisTemplate.opsForValue().get(cacheKey);
if (cachedValue != null) {
return cachedValue;
}
// 从数据库或规则引擎获取
String processedValue = processValue(original, type);
// 存入缓存,设置过期时间
redisTemplate.opsForValue()
.set(cacheKey, processedValue, CACHE_TTL, TimeUnit.SECONDS);
return processedValue;
}
// 批量缓存操作
public Map<String, String> batchGetDesensitized(Map<String, DesensitizeType> originalMap) {
// 批量获取缓存
List<String> cacheKeys = originalMap.entrySet().stream()
.map(entry -> buildCacheKey(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
List<Object> cachedValues = redisTemplate.opsForValue().multiGet(cacheKeys);
// 处理缓存未命中的数据
Map<String, String> result = new HashMap<>();
// ... 批量缓存处理逻辑
return result;
}
// 清除缓存
public void invalidateCache(String original, DesensitizeType type) {
String cacheKey = buildCacheKey(original, type);
redisTemplate.delete(cacheKey);
}
}
REST API 接口实现
@RestController
@RequestMapping("/api/desensitize")
public class DesensitizeController {
@Autowired
private DesensitizationService desensitizationService;
@Autowired
private DistributedCacheManager cacheManager;
// 单个字段脱敏
@PostMapping("/field")
public ApiResponse<String> desensitizeField(
@RequestParam String value,
@RequestParam DesensitizeType type) {
String result = desensitizationService.desensitize(value, type);
return ApiResponse.success(result);
}
// 批量脱敏
@PostMapping("/batch")
public ApiResponse<Map<String, String>> batchDesensitize(
@RequestBody BatchDesensitizeRequest request) {
Map<String, String> result =
desensitizationService.batchDesensitize(request.getDataMap());
return ApiResponse.success(result);
}
// 结构化数据脱敏
@PostMapping("/object")
public ApiResponse<Object> desensitizeObject(
@RequestBody Object data) {
Object result = desensitizationService.desensitizeObject(data, data.getClass());
return ApiResponse.success(result);
}
// 动态更新脱敏规则
@PostMapping("/rule")
public ApiResponse<Void> updateRule(
@RequestBody DesensitizeRuleUpdateRequest request) {
// 更新规则
desensitizationService.updateRule(request.getRule());
// 清除相关缓存
cacheManager.invalidateCacheByRule(request.getRule().getType());
return ApiResponse.success();
}
// 健康检查
@GetMapping("/health")
public ApiResponse<Map<String, Object>> healthCheck() {
Map<String, Object> healthInfo = new HashMap<>();
healthInfo.put("status", "UP");
healthInfo.put("cacheHitRate", cacheManager.getHitRate());
return ApiResponse.success(healthInfo);
}
}
分布式锁支持
@Component
public class DesensitizeDistributedLock {
@Autowired
private RedissonClient redissonClient;
private static final String LOCK_PREFIX = "desensitize:lock:";
// 分布式事务处理
public <T> T executeWithLock(String resourceId, LockCallback<T> callback) {
String lockKey = LOCK_PREFIX + resourceId;
RLock lock = redissonClient.getLock(lockKey);
try {
// 尝试获取锁,最多等待5秒
boolean isLocked = lock.tryLock(5, 10, TimeUnit.SECONDS);
if (isLocked) {
return callback.execute();
} else {
throw new LockAcquisitionException("获取分布式锁失败");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("分布式锁操作被中断", e);
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
@FunctionalInterface
public interface LockCallback<T> {
T execute();
}
}
配置与部署
application.yml配置
desensitize:
# 缓存配置
cache:
enabled: true
type: redis
ttl: 3600
max-size: 10000
# 规则配置
rules:
- name: phone
type: PHONE
enabled: true
pattern: "(\d{3})\d{4}(\d{4})"
replacement: "$1****$2"
- name: id-card
type: ID_CARD
enabled: true
# 分布式配置
distributed:
lock:
enabled: true
timeout: 10000
event:
type: REDIS_PUB_SUB
topic: desensitize:config:change
服务发现与负载均衡
@Configuration
public class DesensitizeServiceConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 服务实例管理
@Bean
public ServiceInstanceManager serviceInstanceManager(
DiscoveryClient discoveryClient,
Registration registration) {
return new ServiceInstanceManager(discoveryClient, registration);
}
}
监控与运维
性能监控
@Component
@Slf4j
public class DesensitizeMonitor {
private final MeterRegistry meterRegistry;
// 统计脱敏请求量
public void recordRequest(DesensitizeType type) {
Counter.builder("desensitize.request.count")
.tag("type", type.name())
.register(meterRegistry)
.increment();
}
// 统计处理时间
public void recordProcessingTime(DesensitizeType type, long duration) {
Timer.builder("desensitize.processing.time")
.tag("type", type.name())
.register(meterRegistry)
.record(duration, TimeUnit.MILLISECONDS);
}
// 缓存命中率
public void recordCacheHit(boolean hit) {
Counter.builder("desensitize.cache")
.tag("result", hit ? "hit" : "miss")
.register(meterRegistry)
.increment();
}
}
日志记录
@Aspect
@Component
@Slf4j
public class DesensitizeLogAspect {
@Around("@annotation(LogDesensitize)")
public Object logDesensitizeOperation(ProceedingJoinPoint point) throws Throwable {
long startTime = System.currentTimeMillis();
try {
Object result = point.proceed();
log.info("脱敏操作完成 - 方法: {}, 耗时: {}ms, 参数: {}, 结果: {}",
point.getSignature().getName(),
System.currentTimeMillis() - startTime,
maskSensitiveInfo(point.getArgs()),
maskSensitiveInfo(result));
return result;
} catch (Exception e) {
log.error("脱敏操作失败 - 方法: {}, 耗时: {}ms, 错误: {}",
point.getSignature().getName(),
System.currentTimeMillis() - startTime,
e.getMessage());
throw e;
}
}
private Object maskSensitiveInfo(Object obj) {
if (obj instanceof String) {
String str = (String) obj;
if (str.length() > 4) {
return str.substring(0, 2) + "****" + str.substring(str.length() - 2);
}
}
return obj;
}
}
使用示例
SDK使用方式
// 1. 简单使用
String phone = "13812345678";
String maskedPhone = DesensitizeUtils.desensitizePhone(phone);
// 结果: 138****5678
// 2. 注解方式
@Data
public class UserVO {
@Desensitize(type = NAME)
private String name;
@Desensitize(type = PHONE)
private String phone;
@Desensitize(type = ID_CARD)
private String idCard;
}
// 3. 批量处理
List<UserVO> users = userService.getUsers();
List<UserVO> desensitizedUsers = desensitizationService
.desensitizeList(users, UserVO.class);
API调用
# 单个字段脱敏
curl -X POST "http://localhost:8080/api/desensitize/field" \
-H "Content-Type: application/json" \
-d '{
"value": "13812345678",
"type": "PHONE"
}'
# 批量脱敏
curl -X POST "http://localhost:8080/api/desensitize/batch" \
-H "Content-Type: application/json" \
-d '{
"dataMap": {
"phone": "13812345678",
"idCard": "110101199001011234"
}
}'
# 对象脱敏
curl -X POST "http://localhost:8080/api/desensitize/object" \
-H "Content-Type: application/json" \
-d '{
"name": "张三",
"phone": "13812345678"
}'
性能优化建议
- 缓存策略:使用本地缓存+Redis多级缓存
- 批量处理:使用管道批量处理
- 异步处理:非关键路径使用异步处理
- 连接池优化:合理配置线程池和连接池
- 预热机制:启动时预加载常见规则
这个实现方案提供了完整的分布式数据脱敏API,支持高并发、动态配置、监控告警等企业级特性。