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

Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
<p>在 Java 中,可以通过自定义注解 + AOP(或手动反射拦截)的方式,在方法抛出 <code>SQLException</code> 时自动过滤掉含表名、字段名等敏感信息的日志。核心思路是:标记敏感方法 → 捕获异常 → 解析堆栈/日志内容 → 替换或屏蔽关键结构信息。</p>
<H3>定义 @SensitiveSql 注解</H3>
<p>用于标记可能执行 SQL 且需保护表结构的方法:</p>
<p><font color="gray">// 保留运行时可见,可作用于方法</font></p>
<pre><code>@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveSql {
String value() default "";
}</code></pre>
<H3>在方法上使用注解</H3>
<p>标注实际执行数据库操作的方法,例如 DAO 层方法:</p>
<pre><code>public class UserDao {
@SensitiveSql
public List<User> findByEmail(String email) {
// 可能触发 SELECT * FROM users WHERE email = ?
return jdbcTemplate.query(...);
}
}</code></pre>
<H3>通过反射+异常处理器隐藏敏感日志</H3>
<p>不依赖 Spring AOP 时,可在通用异常处理逻辑中用反射检查调用栈:</p>
<ul>
<li>捕获 <code>SQLException</code> 或其子类(如 <code>MySQLSyntaxErrorException</code>、<code>PSQLException</code>)</li>
<li>遍历当前线程的栈帧,找到最近被 <code>@SensitiveSql</code> 标记的方法</li>
<li>若匹配成功,则对异常消息做脱敏:替换表名(<code>users</code>→<code>[TABLE]</code>)、字段名(<code>email</code>→<code>[COLUMN]</code>)、SQL 片段(正则匹配 <code>FROMs+w+</code>、<code>SELECTs+[w, ]+s+FROM</code> 等)</li>
<li>推荐使用预编译正则避免重复编译,例如:<br>
<code>Pattern TABLE_PATTERN = Pattern.compile("(?i)from\s+([a-zA-Z_][a-zA-Z0-9_]*)", Pattern.CASE_INSENSITIVE);</code></li>
</ul>
<H3>日志输出前统一脱敏(推荐落地方式)</H3>
<p>更健壮的做法是把脱敏逻辑下沉到日志框架(如 Logback)的 <code>Filter</code> 或 <code>Layout</code> 中:</p>
<ul>
<li>自定义 <code>LoggingEvent</code> 处理器,检查异常类型和调用栈是否命中 <code>@SensitiveSql</code></li>
<li>对 <code>event.getThrowableProxy().getClassName()</code> 和 <code>getMessage()</code> 做关键词清洗</li>
<li>避免直接打印原始 SQL(尤其不要在 <code>catch</code> 块里写 <code>e.printStackTrace()</code>)</li>
<li>生产环境应关闭 <code>show-sql</code>,禁用 Hibernate 的 <code>format_sql</code>,防止日志泄露</li>
</ul>

















