java敏感詞過(guò)濾的實(shí)現(xiàn)方式
在論壇、聊天、評(píng)論等用戶生成內(nèi)容(UGC)為核心的功能中,完全依賴用戶自覺(jué)是不現(xiàn)實(shí)的。
為了防止個(gè)別用戶發(fā)布違規(guī)、廣告或惡意言論,從而污染社區(qū)環(huán)境、帶來(lái)法律風(fēng)險(xiǎn)或傷害其他用戶,我們需要自行搭建敏感詞過(guò)濾系統(tǒng)來(lái)防御。
1.引入依賴
<!-- 敏感詞工具包 -->
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>sensitive-word</artifactId>
<version>0.21.0</version>
</dependency>2.定義自定義敏感詞類
package com.heyin.sass.portal.util.sensitive;
import com.github.houbb.sensitive.word.api.IWordDeny;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/**
* @author zenghuilin
*/
@Slf4j
public class MyWordDeny implements IWordDeny {
@Override
public List<String> deny() {
List<String> list = new ArrayList<>();
try {
Resource mySensitiveWords = new ClassPathResource("sensitive/sensitive_word_deny.txt");
Path mySensitiveWordsPath = Paths.get(mySensitiveWords.getFile().getPath());
list = Files.readAllLines(mySensitiveWordsPath, StandardCharsets.UTF_8);
} catch (IOException ioException) {
log.error("讀取敏感詞文件錯(cuò)誤!" + ioException.getMessage());
}
return list;
}
}3.定義自定義非敏感類
package com.heyin.sass.portal.util.sensitive;
import com.github.houbb.sensitive.word.api.IWordAllow;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/**
* @author zenghuilin
*/
@Slf4j
public class MyWordAllow implements IWordAllow {
@Override
public List<String> allow() {
List<String> list = new ArrayList<>();
try {
Resource mySensitiveWords = new ClassPathResource("sensitive/sensitive_word_allow.txt");
Path mySensitiveWordsPath = Paths.get(mySensitiveWords.getFile().getPath());
list = Files.readAllLines(mySensitiveWordsPath, StandardCharsets.UTF_8);
} catch (IOException ioException) {
log.error("讀取敏感詞文件錯(cuò)誤!" + ioException.getMessage());
}
return list;
}
}4.定義自定義替換詞類
package com.heyin.sass.portal.util.sensitive;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import com.github.houbb.sensitive.word.api.IWordContext;
import com.github.houbb.sensitive.word.api.IWordReplace;
import com.github.houbb.sensitive.word.api.IWordResult;
import com.github.houbb.sensitive.word.utils.InnerWordCharUtils;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* @author zenghuilin
*/
@Slf4j
public class MyWordReplace implements IWordReplace {
private static final Map<String, String> SENSITIVE_WORD_MAP = new HashMap<>();
static {
try {
// 使用 ClassPathResource 加載文件
Resource resource = new ClassPathResource("sensitive/sensitive_word_replace.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8));
// 逐行讀取文件
String line;
while ((line = reader.readLine()) != null) {
// 將每行按逗號(hào)分割成 key 和 value
String[] parts = line.split(",");
if (parts.length == 2) {
SENSITIVE_WORD_MAP.put(parts[0], parts[1]); // 將 a,b 形式加入到Map中
}
}
reader.close();
} catch (Exception e) {
log.info("初始化SENSITIVE_WORD_MAP失?。簕}", e.getMessage());
}
}
@Override
public void replace(StringBuilder stringBuilder, final char[] rawChars, IWordResult wordResult, IWordContext wordContext) {
String sensitiveWord = InnerWordCharUtils.getString(rawChars, wordResult);
// 自定義不同的敏感詞替換策略,可以從數(shù)據(jù)庫(kù)等地方讀取
if (SENSITIVE_WORD_MAP.containsKey(sensitiveWord)) {
stringBuilder.append(SENSITIVE_WORD_MAP.get(sensitiveWord));
} else {
// 其他默認(rèn)使用 * 代替
int wordLength = wordResult.endIndex() - wordResult.startIndex();
for (int i = 0; i < wordLength; i++) {
stringBuilder.append('*');
}
}
}
}5.最后定義工具類
package com.heyin.sass.portal.util.sensitive;
import com.github.houbb.sensitive.word.api.IWordAllow;
import com.github.houbb.sensitive.word.api.IWordDeny;
import com.github.houbb.sensitive.word.api.IWordReplace;
import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
import com.github.houbb.sensitive.word.support.allow.WordAllows;
import com.github.houbb.sensitive.word.support.deny.WordDenys;
import java.util.List;
/**
* @author zenghuilin
*/
public class SensitiveWordUtil {
private static final SensitiveWordBs SENSITIVE_WORD_BS;
static {
// 配置默認(rèn)敏感詞 + 自定義敏感詞
IWordDeny wordDeny = WordDenys.chains(WordDenys.defaults(), new MyWordDeny());
// 配置默認(rèn)非敏感詞 + 自定義非敏感詞
IWordAllow wordAllow = WordAllows.chains(WordAllows.defaults(), new MyWordAllow());
// 配置自定義替換詞
IWordReplace wordReplace = new MyWordReplace();
SENSITIVE_WORD_BS = SensitiveWordBs.newInstance()
// 忽略大小寫(xiě)
.ignoreCase(true)
// 忽略半角圓角
.ignoreWidth(true)
// 忽略數(shù)字的寫(xiě)法
.ignoreNumStyle(true)
// 忽略中文的書(shū)寫(xiě)格式:簡(jiǎn)繁體
.ignoreChineseStyle(true)
// 忽略英文的書(shū)寫(xiě)格式
.ignoreEnglishStyle(true)
// 忽略重復(fù)詞
.ignoreRepeat(false)
// 是否啟用數(shù)字檢測(cè)
.enableNumCheck(false)
// 是否啟用郵箱檢測(cè)
.enableEmailCheck(false)
// 是否啟用鏈接檢測(cè)
.enableUrlCheck(false)
// 數(shù)字檢測(cè),自定義指定長(zhǎng)度
// .numCheckLen(8)
// 配置自定義敏感詞
.wordDeny(wordDeny)
// 配置非自定義敏感詞
.wordAllow(wordAllow)
// 配置自定義替換詞
.wordReplace(wordReplace)
.init();
}
/**
* 刷新敏感詞庫(kù)與非敏感詞庫(kù)緩存
*/
public static void refresh() {
SENSITIVE_WORD_BS.init();
}
/**
* 判斷是否含有敏感詞
*
* @param text
* @return
*/
public static boolean contains(String text) {
return SENSITIVE_WORD_BS.contains(text);
}
/**
* 替換敏感詞
*
* @param text
* @return
*/
public static String replace(String text) {
return SENSITIVE_WORD_BS.replace(text);
}
/**
* 返回所有敏感詞
*
* @param text
* @return
*/
public static List<String> findAll(String text) {
return SENSITIVE_WORD_BS.findAll(text);
}
public static void main(String[] args) {
String text = "五星紅旗迎風(fēng)飄揚(yáng)";
System.out.println(findAll(text));
String replace = replace(text);
System.out.println(replace);
}
}6.資源文件放在src/main/resouces目錄下

敏感詞文件和非敏感詞文件,一個(gè)詞一行

替換詞文件,前面是敏感詞,后面是想要替換的詞

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Java實(shí)現(xiàn)一個(gè)敏感詞過(guò)濾有哪些方法以及怎么優(yōu)化詳解
- 基于Java語(yǔ)言開(kāi)發(fā)的一個(gè)高效的敏感詞過(guò)濾工具
- Java 過(guò)濾器實(shí)現(xiàn)敏感詞匯過(guò)濾功能
- Java使用DFA算法實(shí)現(xiàn)敏感詞過(guò)濾的示例代碼
- JAVA使用前綴樹(shù)(Tire樹(shù))實(shí)現(xiàn)敏感詞過(guò)濾、詞典搜索
- Java實(shí)戰(zhàn)之敏感詞過(guò)濾器
- Java實(shí)現(xiàn)DFA算法對(duì)敏感詞、廣告詞過(guò)濾功能示例
相關(guān)文章
Eclipse中查看android工程代碼出現(xiàn)"android.jar has no source attachment
這篇文章主要介紹了Eclipse中查看android工程代碼出現(xiàn)"android.jar has no source attachment"的解決方案,需要的朋友可以參考下2016-05-05
SpringBoot調(diào)用WebService接口方法示例代碼
這篇文章主要介紹了使用SpringWebServices調(diào)用SOAP?WebService接口的步驟,包括導(dǎo)入依賴、創(chuàng)建請(qǐng)求類和響應(yīng)類、生成ObjectFactory類、配置WebServiceTemplate、調(diào)用WebService接口以及測(cè)試代碼,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-02-02
springboot集成shiro詳細(xì)總結(jié)
這幾天在看 shiro,用 springboot 集成了一下,下面的這個(gè)例子中主要介紹了 shiro 的認(rèn)證和授權(quán),以及鹽值加密的功能.程序可以運(yùn)行起來(lái).這里只做一個(gè)簡(jiǎn)單的介紹,后續(xù)會(huì)針對(duì)各個(gè)功能做一個(gè)詳細(xì)的介紹,這里不做過(guò)多的贅述,需要的朋友可以參考下2021-05-05
JDBC連接數(shù)據(jù)庫(kù)步驟及基本操作示例詳解
這篇文章主要為大家介紹了JDBC連接數(shù)據(jù)庫(kù)步驟及基本操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
java實(shí)現(xiàn)簡(jiǎn)單超市管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單超市管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01
Java運(yùn)行時(shí)數(shù)據(jù)區(qū)劃分原理解析
這篇文章主要介紹了Java運(yùn)行時(shí)數(shù)據(jù)區(qū)劃分原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04

