在企业级 Java 开发中,日志往往是最重要的“真相记录者”——它精准地还原了系统运行的全过程。然而,日志也可能成为“信息泄露的温床”:用户身份证号、手机号、银行卡号、甚至密码,可能在日志中赤裸裸地暴露出来。 这不仅违反合规要求(如《个人信息保护法》《GDPR》),还可能给企业带来不可估量的安全风险。
那么,有没有一种优雅的方式,既能记录日志,又能自动隐藏敏感信息? 答案是肯定的——这就是Sensitive 框架。
本文将带你从零上手这一轻量却强大的日志脱敏工具,详解其核心功能、实战用法、与日志框架的无缝集成方案,以及在高并发场景下的性能优化技巧。
Sensitive 框架
Sensitive 是一款由社区开发者houbb打造的开源Java脱敏工具框架。 它的设计理念非常纯粹:让日志在保留业务可读性的同时,自动屏蔽敏感数据。
框架基于注解驱动,开发者只需在类字段上添加注解,即可让框架在运行时动态识别并脱敏数据。 无需手写字符串替换逻辑,也不用担心遗漏任何敏感字段。
框架内部基于以下理念设计:
注解驱动→ 简化使用方式;
策略化脱敏→ 不同信息类型匹配不同规则;
可扩展性强→ 支持自定义策略与条件;
可深度集成→ 无缝对接 Logback、Log4j2;
性能优先→ 支持深拷贝与缓存机制。
核心功能
基于注解的自动脱敏
通过在字段上添加@Sensitive注解并指定策略类,Sensitive 就能自动识别敏感数据并进行脱敏处理。
package com.icoderoad.sensitive.model; import com.github.houbb.sensitive.annotation.Sensitive; import com.github.houbb.sensitive.core.api.strategy.*; import lombok.Getter;import lombok.Setter; @Getter@Setterpublic class User { @Sensitive(strategy = StrategyChineseName.class) private String username; @Sensitive(strategy = StrategyCardId.class) private String idCard; @Sensitive(strategy = StrategyPassword.class) private String password; }只需这样简单的注解标记,当日志打印User对象时,框架就会自动将这些字段处理成安全格式。
丰富的内置策略库
Sensitive 框架默认内置了多种常见脱敏策略,包括:
中文姓名(
StrategyChineseName)身份证号(
StrategyCardId)手机号(
StrategyPhone)邮箱(
StrategyEmail)密码(
StrategyPassword)
例如手机号13800138000将自动转换为138****8000,邮箱example@qq.com将转换为exa***@qq.com。
自定义脱敏策略
对于项目中的特殊字段(如订单号、业务编号等),你可以实现IStrategy接口来自定义逻辑。
package com.icoderoad.sensitive.strategy; import com.github.houbb.sensitive.api.IContext; import com.github.houbb.sensitive.api.IStrategy; public class CustomStrategy implements IStrategy { @Override public Object des(Object original, IContext context) { String value = (String) original; return value.substring(0, 3) + "***" + value.substring(value.length() - 3); } }在字段上使用:
@Sensitive(strategy = com.icoderoad.sensitive.strategy.CustomStrategy.class) private String orderCode;深拷贝与嵌套对象支持
Sensitive 不仅支持基本对象的脱敏,还支持对包含嵌套对象或集合的复杂结构进行递归脱敏。
package com.icoderoad.sensitive.model; import com.github.houbb.sensitive.annotation.*; import com.github.houbb.sensitive.core.api.strategy.*; import lombok.Data;import java.util.List; @Data public class Order { @SensitiveEntry private User user; @SensitiveEntry private List<Product> products; }测试代码:
Order order = new Order();order.setUser(user); order.setProducts(Arrays.asList(product1, product2)); Order safeOrder = SensitiveUtil.desCopy(order); System.out.println("脱敏前:" + order);System.out.println("脱敏后:" + safeOrder);框架会递归处理内部对象的所有敏感字段,彻底杜绝遗漏。
FastJSON 脱敏输出支持
在 Web 应用中,Sensitive 与 FastJSON 完美兼容,可直接生成脱敏后的 JSON 输出,防止敏感信息通过 API 泄露。
String json = JSON.toJSONString(SensitiveUtil.desCopy(user));条件生效策略(Conditional Desensitization)
可通过实现ICondition接口,让某些脱敏规则仅在特定条件下生效(如仅普通用户脱敏)。
package com.icoderoad.sensitive.condition; import com.github.houbb.sensitive.api.strategy.IContext; import com.github.houbb.sensitive.api.strategy.ICondition; import com.icoderoad.sensitive.model.User; public class NonAdminCondition implements ICondition { @Override public boolean valid(IContext context) { Object obj = context.getCurrentObject(); if (obj instanceof User) { return !((User) obj).isAdmin(); } return false; } }注解使用:
@Sensitive(strategy = StrategyCardId.class, condition = NonAdminCondition.class)private String idCard;环境准备与依赖配置
Maven 依赖配置
<dependency> <groupId>com.github.houbb</groupId> <artifactId>sensitive-core</artifactId> <version>1.7.0</version> </dependency>集成日志框架:
<!-- Logback 支持 --> <dependency> <groupId>com.github.houbb</groupId> <artifactId>sensitive-logback</artifactId> <version>1.7.0</version> </dependency> <!-- Log4j2 支持 --> <dependency> <groupId>com.github.houbb</groupId> <artifactId>sensitive-log4j2</artifactId> <version>1.7.0</version> </dependency>Logback 集成
在/src/main/resources/logback-spring.xml添加
<configuration> <conversionRule conversionWord="sensitive" converterClass="com.github.houbb.sensitive.logback.converter.SensitiveConverter"/> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{HH:mm:ss} [%thread] %-5level %logger{36} - %sensitive(%msg)%n </pattern> </encoder> </appender> <root level="info"> <appender-ref ref="CONSOLE"/> </root> </configuration>只需使用%sensitive(%msg),日志消息自动脱敏。
Log4j2 集成
在/src/main/resources/log4j2.xml中添加
<Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> <Filters> <SensitiveFilter> <Patterns> <Pattern>(\d{3})\d{4}(\d{4})</Pattern> <Pattern>(\d{4})\d{10}(\w{4})</Pattern> </Patterns> <Replacement>$1****$2</Replacement> </SensitiveFilter> </Filters> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>性能优化实践
复用策略对象
避免在高频场景下重复创建策略实例:
public class SensitiveUtils { private static final IStrategy CUSTOM_STRATEGY = new CustomStrategy(); public static Object desensitize(Object value) { return CUSTOM_STRATEGY.des(value, null); } }批量脱敏处理
List<User> sensitiveUsers = SensitiveUtil.desCopyCollection(userList);结果缓存加速
import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; public class SensitiveCache { private static final Cache<String, Object> cache = CacheBuilder.newBuilder().maximumSize(1000).build(); }总结
在数据安全要求愈发严格的今天,Sensitive 框架无疑是 Java 开发者的安全利器。 它通过简洁的注解体系、丰富的内置策略、灵活的扩展机制与日志框架的深度融合,实现了:
一键脱敏日志输出 支持自定义策略与条件逻辑 高性能深拷贝与缓存机制 与 Logback/Log4j2 无缝对接
无论是金融、电商还是政务系统,只要涉及个人隐私数据的日志记录场景,Sensitive 都值得纳入你的安全体系中。
如果你还在为“日志中泄露敏感信息”而焦虑,不妨尝试将 Sensitive 引入你的项目,用更优雅的方式守护数据安全。
未来,期待它能支持更多序列化框架(如 Jackson、Gson)与云原生日志系统,让“安全日志”成为 Java 世界的新标准。