refactor(comment): migrate sensitive word filter to houbb sensitive-word

This commit is contained in:
root
2026-03-08 14:51:22 +08:00
parent bd5af140fe
commit d116403db4
2 changed files with 14 additions and 84 deletions

View File

@@ -104,6 +104,13 @@
<version>5.8.22</version>
</dependency>
<!-- houbb 敏感词过滤 -->
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>sensitive-word</artifactId>
<version>0.34.0</version>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>

View File

@@ -1,17 +1,10 @@
package com.test.musichouduan.service.impl;
import cn.hutool.dfa.SensitiveUtil;
import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
import com.test.musichouduan.exception.BusinessException;
import com.test.musichouduan.service.SensitiveWordService;
import jakarta.annotation.PostConstruct;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
/**
@@ -20,90 +13,20 @@ import java.util.List;
@Service
public class SensitiveWordServiceImpl implements SensitiveWordService {
/**
* 服务启动后加载一次词库
*/
@PostConstruct
public void initSensitiveWords() {
List<String> words = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new ClassPathResource("sensitive-words.txt").getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
String word = line.trim();
// 忽略空行和注释行
if (!word.isEmpty() && !word.startsWith("#")) {
words.add(word);
}
}
} catch (Exception e) {
throw new BusinessException("敏感词词库加载失败");
}
// 若词库为空,直接跳过初始化,避免影响正常启动
if (words.isEmpty()) {
return;
}
try {
// 兼容不同版本 Hutool 的 init 方法签名
Method[] methods = SensitiveUtil.class.getMethods();
for (Method method : methods) {
if (!"init".equals(method.getName())) {
continue;
}
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
Class<?> type = parameterTypes[0];
if (type.isAssignableFrom(List.class) || type.isAssignableFrom(java.util.Collection.class)) {
method.invoke(null, words);
return;
}
if (type.isArray() && type.getComponentType() == String.class) {
method.invoke(null, (Object) words.toArray(new String[0]));
return;
}
}
if (parameterTypes.length == 2) {
Class<?> firstType = parameterTypes[0];
Class<?> secondType = parameterTypes[1];
if ((firstType.isAssignableFrom(List.class) || firstType.isAssignableFrom(java.util.Collection.class))
&& (secondType == boolean.class || secondType == Boolean.class)) {
// 默认关闭异步,确保启动即生效
method.invoke(null, words, false);
return;
}
}
}
throw new BusinessException("敏感词工具初始化失败");
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
throw new BusinessException("敏感词工具初始化失败");
}
}
@Override
public void validateCommentContent(String content) {
if (content == null || content.trim().isEmpty()) {
return;
}
try {
Method containsMethod = SensitiveUtil.class.getMethod("containsSensitive", String.class);
Object result = containsMethod.invoke(null, content);
boolean hasSensitive = result instanceof Boolean && (Boolean) result;
if (hasSensitive) {
// 使用 houbb/sensitive-word 默认内置词库进行检测。
// 当前项目保留了 sensitive-words.txt 作为后续扩展词库参考文件,
// 现阶段未主动加载,避免与默认词库机制产生混淆。
if (SensitiveWordHelper.contains(content)) {
List<String> hitWords = SensitiveWordHelper.findAll(content);
if (!hitWords.isEmpty()) {
throw new BusinessException("评论包含敏感词,请修改后再发布");
}
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
throw new BusinessException("评论敏感词校验失败");
}
}
}