可通过自定义@sensitivesql注解结合反射或日志过滤器,在sqlexception发生时自动脱敏表名、字段名等敏感信息:标记方法→捕获异常→解析调用栈→正则替换sql片段。

<p>在 Java 中,可以通过自定义注解 + AOP(或手动反射拦截)的方式,在方法抛出 <code>SQLException</code> 时自动过滤掉含表名、字段名等敏感信息的日志。核心思路是:标记敏感方法 → 捕获异常 → 解析堆栈/日志内容 → 替换或屏蔽关键结构信息。</p>
<h3>定义 @SensitiveSql 注解</h3>
<p>用于标记可能执行 SQL 且需保护表结构的方法:</p>
<p><font color="gray">// 保留运行时可见,可作用于方法</font></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9040" title="JavaStoryDevelop"><img
src="https://img.php.cn/upload/skill/000/000/081/179238966962420.jpg" alt="JavaStoryDevelop" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill9040" title="JavaStoryDevelop" class="overflowclass">JavaStoryDevelop</a>
<p class="overflowclass">你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在</p>
</div>
<a rel="nofollow" href="/xiazai/skill9040" title="JavaStoryDevelop" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<pre class="brush:php;toolbar:false;"><code>@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveSql {
String value() default "";
}</code>
在方法上使用注解
标注实际执行数据库操作的方法,例如 DAO 层方法:
<code>public class UserDao {
@SensitiveSql
public List<user> findByEmail(String email) {
// 可能触发 SELECT * FROM users WHERE email = ?
return jdbcTemplate.query(...);
}
}</user></code>
通过反射+异常处理器隐藏敏感日志
不依赖 Spring AOP 时,可在通用异常处理逻辑中用反射检查调用栈:
- 捕获
SQLException或其子类(如MySQLSyntaxErrorException、PSQLException) - 遍历当前线程的栈帧,找到最近被
@SensitiveSql标记的方法 - 若匹配成功,则对异常消息做脱敏:替换表名(
users→[TABLE])、字段名(email→[COLUMN])、SQL 片段(正则匹配FROMs+w+、SELECTs+[w, ]+s+FROM等) - 推荐使用预编译正则避免重复编译,例如:
Pattern TABLE_PATTERN = Pattern.compile("(?i)from\s+([a-zA-Z_][a-zA-Z0-9_]*)", Pattern.CASE_INSENSITIVE);
日志输出前统一脱敏(推荐落地方式)
更健壮的做法是把脱敏逻辑下沉到日志框架(如 Logback)的 Filter 或 Layout 中:
- 自定义
LoggingEvent处理器,检查异常类型和调用栈是否命中@SensitiveSql - 对
event.getThrowableProxy().getClassName()和getMessage()做关键词清洗 - 避免直接打印原始 SQL(尤其不要在
catch块里写e.printStackTrace()) - 生产环境应关闭
show-sql,禁用 Hibernate 的format_sql,防止日志泄露
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










