敏感词过滤需覆盖多级评论dto中所有被@sensitivefield标记的字段,通过aop+自定义注解实现递归反射扫描与dfa统一过滤,支持替换策略、忽略大小写及模糊匹配,业务代码零侵入。

在多级评论区(如楼中楼、嵌套回复)的 DTO 转换场景中,敏感词过滤不能只作用于顶层 content 字段,还需覆盖每层子评论的 content、nickname、title 等潜在风险字段。用自定义注解标记 + AOP 统一处理,既能保持 DTO 结构清晰,又避免重复调用过滤逻辑。
注解定义:支持多层级字段标记
定义一个运行时保留、可作用于字段的注解 @SensitiveField,并支持指定替换策略和是否启用模糊匹配:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveField {
String replacement() default "***"; // 替换符,默认星号
boolean ignoreCase() default true; // 是否忽略大小写
boolean fuzzyMatch() default false; // 是否启用 DFA 模糊匹配(如“广 告”带空格)
}
该注解可直接加在 DTO 的任意 String 字段上,包括嵌套对象中的字段(只要反射可访问)。
DTO 设计:扁平化或嵌套结构都适用
例如多级评论 DTO 可能如下(Lombok 简写):
public class CommentDTO {
private Long id;
@SensitiveField(replacement = "**")
private String content;
@SensitiveField(fuzzyMatch = true)
private String nickname;
private List<replydto> replies; // 子回复列表
}
public class ReplyDTO {
@SensitiveField
private String content;
@SensitiveField(ignoreCase = false)
private String authorName;
}</replydto>
注意:无需为嵌套对象额外写过滤逻辑 —— 只要字段被 @SensitiveField 标记,统一处理器就能递归扫描到。
统一过滤处理器:递归 + 反射 + DFA 实例复用
编写一个通用工具类 SensitiveFieldFilter,核心能力包括:
- 接收任意对象(DTO 或其嵌套子对象),深度遍历所有被
@SensitiveField标记的String字段 - 对每个字段值调用已初始化的 DFA 过滤器(单例,词库热更新支持)
- 按注解参数决定是否忽略大小写、是否启用模糊匹配模式
- 使用
Field.setAccessible(true)修改私有字段值,兼容 Lombok
示例调用位置:
// Controller 层接收后立即过滤
@PostMapping("/comments")
public Result addComment(@RequestBody CommentDTO dto) {
SensitiveFieldFilter.filter(dto); // 一行触发全树过滤
commentService.save(dto);
return Result.ok();
}
与 Spring Boot 集成建议
若想进一步解耦,可封装为 @Bean 并配合 @ConfigurationProperties 管理敏感词源(如从数据库或 Nacos 加载):
- 将 DFA 树构建逻辑抽为
SensitiveWordEngine,启动时自动加载词库 - 提供
/api/admin/words/reload接口支持运行时刷新,无需重启 - 在全局 DTO 转换器(如
MappingJackson2HttpMessageConverter的ObjectMapper)中注册反序列化后置处理器,实现「自动过滤」
这样,无论前端传入的是单条评论、还是含 5 层嵌套的 JSON,只要字段打了注解,就自动生效,业务代码零侵入。










