SpringBoot使用SensitiveWord實(shí)現(xiàn)敏感詞過(guò)濾
包含默認(rèn)敏感詞過(guò)濾和自定義敏感詞過(guò)濾。
導(dǎo)入依賴
<dependency> <groupId>com.github.houbb</groupId> <artifactId>sensitive-word</artifactId> <version>0.2.0</version> </dependency>
方法
方法 | 參數(shù) | 返回值 | 說(shuō)明 |
---|---|---|---|
contains(String) | 待驗(yàn)證的字符串 | 布爾值 | 驗(yàn)證字符串是否包含敏感詞 |
replace(String, ISensitiveWordReplace) | 使用指定的替換策略替換敏感詞 | 字符串 | 返回脫敏后的字符串 |
replace(String, char) | 使用指定的 char 替換敏感詞 | 字符串 | 返回脫敏后的字符串 |
replace(String) | 使用 * 替換敏感詞 | 字符串 | 返回脫敏后的字符串 |
findAll(String) | 待驗(yàn)證的字符串 | 字符串列表 | 返回字符串中所有敏感詞 |
findFirst(String) | 待驗(yàn)證的字符串 | 字符串 | 返回字符串中第一個(gè)敏感詞 |
findAll(String, IWordResultHandler) | IWordResultHandler 結(jié)果處理類 | 字符串列表 | 返回字符串中所有敏感詞 |
findFirst(String, IWordResultHandler) | IWordResultHandler 結(jié)果處理類 | 字符串 | 返回字符串中第一個(gè)敏感詞 |
ISensitiveWordReplace:敏感詞替換策略。
IWordResultHandler:結(jié)果處理??梢詫?duì)敏感詞的結(jié)果進(jìn)行處理,允許用戶自定義。內(nèi)置了WordResultHandlers 工具類。
- WordResultHandlers.word():只保留敏感詞單詞本身。
- WordResultHandlers.raw():保留敏感詞相關(guān)信息,包含敏感詞以及敏感詞對(duì)應(yīng)的開始和結(jié)束下標(biāo)。
默認(rèn)示例
使用默認(rèn)提供的方法。
@Test void testWord() { String text = "紅旗迎風(fēng)飄揚(yáng),主席的畫像屹立在天安門前。"; System.out.println(SensitiveWordHelper.contains(text)); System.out.println(SensitiveWordHelper.replace(text)); System.out.println(SensitiveWordHelper.replace(text, '0')); System.out.println(SensitiveWordHelper.findFirst(text)); System.out.println(SensitiveWordHelper.findFirst(text, WordResultHandlers.word())); System.out.println(SensitiveWordHelper.findFirst(text, WordResultHandlers.raw())); System.out.println(SensitiveWordHelper.findAll(text)); System.out.println(SensitiveWordHelper.findAll(text, WordResultHandlers.word())); System.out.println(SensitiveWordHelper.findAll(text, WordResultHandlers.raw())); }
輸出:
Init sensitive word map end! Cost time: 163ms
true
****迎風(fēng)飄揚(yáng),***的畫像屹立在***前。
0000迎風(fēng)飄揚(yáng),000的畫像屹立在000前。
紅旗
紅旗
WordResult{word='紅旗', startIndex=0, endIndex=4}
[紅旗, 主席, 天安門]
[紅旗, 主席, 天安門]
[WordResult{word='紅旗', startIndex=0, endIndex=4}, WordResult{word='主席', startIndex=9, endIndex=12}, WordResult{word='天安門', startIndex=18, endIndex=21}]
自定義替換策略示例
采用自定義的替換策略實(shí)現(xiàn)。首先需要實(shí)現(xiàn) ISensitiveWordReplace接口自定義替換策略:
package com.tothefor; import com.github.houbb.heaven.util.lang.CharUtil; import com.github.houbb.sensitive.word.api.ISensitiveWordReplace; import com.github.houbb.sensitive.word.api.ISensitiveWordReplaceContext; public class MySensitiveWordReplace implements ISensitiveWordReplace { @Override public String replace(ISensitiveWordReplaceContext context) { String sensitiveWord = context.sensitiveWord(); // 自定義不同的敏感詞替換策略,可以從數(shù)據(jù)庫(kù)等地方讀取 if ("紅旗".equals(sensitiveWord)) { return "旗幟"; } if ("天安門".equals(sensitiveWord)) { return "門"; } if ("主席".equals(sensitiveWord)) { return "教員"; } // 其他默認(rèn)使用 * 代替 int wordLength = context.wordLength(); return CharUtil.repeat('*', wordLength); } }
使用:
@Test void testWord() { String text = "紅旗迎風(fēng)飄揚(yáng),主席的畫像屹立在天安門前。"; System.out.println(SensitiveWordHelper.contains(text)); System.out.println(SensitiveWordHelper.replace(text, new MySensitiveWordReplace())); String text1 = "最好的記憶不如最淡的墨水。"; System.out.println(SensitiveWordHelper.contains(text1)); System.out.println(SensitiveWordHelper.replace(text1, new MySensitiveWordReplace())); }
輸出:
Init sensitive word map end! Cost time: 16ms
true
旗幟迎風(fēng)飄揚(yáng),教員的畫像屹立在門前。
false
最好的記憶不如最淡的墨水。
自定義
點(diǎn)進(jìn) SensitiveWordHelper 源碼,可以看見以下代碼:
private static final SensitiveWordBs WORD_BS = SensitiveWordBs.newInstance().init();
而且可以發(fā)現(xiàn),方法也都是調(diào)用的 SensitiveWordBs 類的方法。所以,可以理解成 SensitiveWordHelper 只是對(duì) SensitiveWordBs 的一層封裝,而之所以封裝就是為了提供給開發(fā)者針對(duì)簡(jiǎn)單場(chǎng)景的快速的使用。
而且從上面的創(chuàng)建語(yǔ)句中可以看見,沒(méi)有加任何其他的東西,就只是初始化了一個(gè),這也是最簡(jiǎn)單的。接下來(lái)就是自定義 SensitiveWordBs 實(shí)現(xiàn)敏感詞過(guò)濾。
自定義SensitiveWordBs
下來(lái)看有哪些參數(shù)可以加,各項(xiàng)配置的說(shuō)明如下:
序號(hào) | 方法 | 說(shuō)明 |
---|---|---|
1 | ignoreCase | 忽略大小寫 |
2 | ignoreWidth | 忽略半角圓角 |
3 | ignoreNumStyle | 忽略數(shù)字的寫法 |
4 | ignoreChineseStyle | 忽略中文的書寫格式 |
5 | ignoreEnglishStyle | 忽略英文的書寫格式 |
6 | ignoreRepeat | 忽略重復(fù)詞 |
7 | enableNumCheck | 是否啟用數(shù)字檢測(cè)。默認(rèn)連續(xù) 8 位數(shù)字認(rèn)為是敏感詞 |
8 | enableEmailCheck | 是有啟用郵箱檢測(cè) |
9 | enableUrlCheck | 是否啟用鏈接檢測(cè) |
然后創(chuàng)建自定義的 SensitiveWordBs,如下:
package com.tothefor.motorcode.core.SensitiveWord; 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 org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SensitiveWordConfig { @Autowired private CustomWordAllow customWordAllow; @Autowired private CustomWordDeny customWordDeny; /** * 初始化引導(dǎo)類 * * @return 初始化引導(dǎo)類 * @since 1.0.0 */ @Bean public SensitiveWordBs sensitiveWordBs() { // 可根據(jù)數(shù)據(jù)庫(kù)數(shù)據(jù)判斷 動(dòng)態(tài)增加配置 return SensitiveWordBs.newInstance() .wordDeny(WordDenys.chains(WordDenys.system(),customWordDeny)) // 設(shè)置黑名單 .wordAllow(WordAllows.chains(WordAllows.system(), customWordAllow)) // 設(shè)置白名單 .ignoreCase(true) .ignoreWidth(true) .ignoreNumStyle(true) .ignoreChineseStyle(true) .ignoreEnglishStyle(true) .ignoreRepeat(true) .enableEmailCheck(true) .enableUrlCheck(true) // 各種其他配置 .init(); } }
其中,wordDeny、wordAllow是自定義敏感詞的黑名單和白名單??梢栽O(shè)置單個(gè),也可以設(shè)置多個(gè)。如下:
// 設(shè)置系統(tǒng)默認(rèn)敏感詞 SensitiveWordBs wordBs = SensitiveWordBs.newInstance() .wordDeny(WordDenys.system()) // 黑名單 .wordAllow(WordAllows.system()) // 白名單 .init(); // 設(shè)置自定義敏感詞 SensitiveWordBs wordBs = SensitiveWordBs.newInstance() .wordDeny(new MyWordDeny()) .wordAllow(new MyWordAllow()) .init(); // 設(shè)置多個(gè)敏感詞,系統(tǒng)默認(rèn)和自定義 IWordDeny wordDeny = WordDenys.chains(WordDenys.system(), new MyWordDeny()); IWordAllow wordAllow = WordAllows.chains(WordAllows.system(), new MyWordAllow()); SensitiveWordBs wordBs = SensitiveWordBs.newInstance() .wordDeny(wordDeny) .wordAllow(wordAllow) .init();
接下來(lái)再加自定義敏感詞配置。
自定義敏感詞白名單
自定義有哪一些是敏感詞白名單,如果遇見是需要進(jìn)行展示的。通過(guò)實(shí)現(xiàn) IWordAllow 接口重寫 allow() 方法返回白名單敏感詞。
package com.tothefor.motorcode.core.SensitiveWord; import com.github.houbb.sensitive.word.api.IWordAllow; import org.springframework.stereotype.Service; import java.util.Arrays; import java.util.List; @Service public class CustomWordAllow implements IWordAllow { /** * 允許的內(nèi)容-返回的內(nèi)容不被當(dāng)做敏感詞 * @return */ @Override public List<String> allow() { // 從數(shù)據(jù)庫(kù)中查詢白名單敏感詞 return Arrays.asList("紅旗"); } }
自定義敏感詞黑名單
增加敏感詞黑名單。通過(guò)實(shí)現(xiàn) IWordDeny 接口重寫 deny() 方法返回黑名單敏感詞。
package com.tothefor.motorcode.core.SensitiveWord; import com.github.houbb.sensitive.word.api.IWordDeny; import org.springframework.stereotype.Service; import java.util.Arrays; import java.util.List; /** * 自定義敏感詞 */ @Service public class CustomWordDeny implements IWordDeny { /** * 拒絕出現(xiàn)的數(shù)據(jù)-返回的內(nèi)容被當(dāng)做是敏感詞 * * @return */ @Override public List<String> deny() { // 從數(shù)據(jù)庫(kù)中查詢自定義敏感詞 return Arrays.asList("紅旗"); } }
示例
測(cè)試自定義使用:
@Autowired private SensitiveWordBs sensitiveWordBs; @Test void testWord() { String text = "紅旗迎風(fēng)飄揚(yáng),主席的畫像屹立在天安門前。"; System.out.println(sensitiveWordBs.contains(text)); System.out.println(sensitiveWordBs.replace(text)); System.out.println(sensitiveWordBs.replace(text, '0')); System.out.println(sensitiveWordBs.replace(text, new MySensitiveWordReplace())); System.out.println(sensitiveWordBs.findFirst(text)); System.out.println(sensitiveWordBs.findFirst(text, WordResultHandlers.word())); System.out.println(sensitiveWordBs.findFirst(text, WordResultHandlers.raw())); System.out.println(sensitiveWordBs.findAll(text)); System.out.println(sensitiveWordBs.findAll(text, WordResultHandlers.word())); System.out.println(sensitiveWordBs.findAll(text, WordResultHandlers.raw())); }
輸出:
true
紅旗迎風(fēng)飄揚(yáng),***的畫像屹立在***前。
紅旗迎風(fēng)飄揚(yáng),000的畫像屹立在000前。
紅旗迎風(fēng)飄揚(yáng),教員的畫像屹立在門前。
主席
主席
WordResult{word='主席', startIndex=9, endIndex=12}
[主席, 天安門]
[主席, 天安門]
[WordResult{word='主席', startIndex=9, endIndex=12}, WordResult{word='天安門', startIndex=18, endIndex=21}]
可以看見,和之前的有一點(diǎn)不一樣。‘紅旗’ 并沒(méi)有被過(guò)濾掉,主要原因就是因?yàn)槲覀兊淖远x敏感詞白名單中加入了 ‘紅旗’ ,所以沒(méi)有被過(guò)濾掉。但是黑名單中又有這個(gè)詞,為什么沒(méi)有被過(guò)濾掉?這里有個(gè)點(diǎn)就是:如果黑名單和白名單中都有同一個(gè)敏感詞,那么這個(gè)詞是不會(huì)被過(guò)濾的。
重置詞庫(kù)
因?yàn)槊舾性~庫(kù)的初始化較為耗時(shí),建議程序啟動(dòng)時(shí)做一次 init 初始化。但為了保證敏感詞修改可以實(shí)時(shí)生效且保證接口的盡可能簡(jiǎn)化,可以在數(shù)據(jù)庫(kù)詞庫(kù)發(fā)生變更時(shí),需要詞庫(kù)生效,主動(dòng)觸發(fā)一次初始化 sensitiveWordBs.init()。因?yàn)樵谡{(diào)用 sensitiveWordBs.init() 的時(shí)候,根據(jù) IWordDeny+IWordAllow 重新構(gòu)建敏感詞庫(kù)。因?yàn)槌跏蓟赡芎臅r(shí)較長(zhǎng)(秒級(jí)別),所有優(yōu)化為 init 未完成時(shí)不影響舊的詞庫(kù)功能,完成后以新的為準(zhǔn)。
@Autowired private SensitiveWordBs sensitiveWordBs; sensitiveWordBs.init();
每次數(shù)據(jù)庫(kù)的信息發(fā)生變化之后,首先調(diào)用更新數(shù)據(jù)庫(kù)敏感詞庫(kù)的方法,然后調(diào)用這個(gè)方法。但不推薦將此方法放在數(shù)據(jù)庫(kù)被修改后就調(diào)用,而推薦單獨(dú)開一個(gè)接口,手動(dòng)調(diào)用。
總結(jié)
所有的操作均是在 SensitiveWordBs 上操作的。
以上就是SpringBoot使用SensitiveWord實(shí)現(xiàn)敏感詞過(guò)濾的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot SensitiveWord敏感詞過(guò)濾的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java動(dòng)態(tài)代理(jdk與cglib)詳細(xì)解析
靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼,再對(duì)其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了2013-09-09測(cè)量Java對(duì)象所占內(nèi)存大小方式
這篇文章主要介紹了測(cè)量Java對(duì)象所占內(nèi)存大小方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09Java中的數(shù)組排序方式(快速排序、冒泡排序、選擇排序)
這篇文章主要介紹了Java中的數(shù)組排序方式(快速排序、冒泡排序、選擇排序),需要的朋友可以參考下2014-02-02SpringBoot配置項(xiàng)目訪問(wèn)路徑URL的根路徑方式
這篇文章主要介紹了SpringBoot配置項(xiàng)目訪問(wèn)路徑URL的根路徑方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01Java加密 消息摘要算法MAC實(shí)現(xiàn)詳解
這篇文章主要介紹了Java 消息摘要算法MAC實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07MyBatis分頁(yè)查詢返回list的時(shí)候出現(xiàn)null的問(wèn)題
這篇文章主要介紹了MyBatis分頁(yè)查詢返回list的時(shí)候出現(xiàn)null的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07詳解備忘錄模式及其在Java設(shè)計(jì)模式編程中的實(shí)現(xiàn)
這篇文章主要介紹了詳解備忘錄模式及其在Java設(shè)計(jì)模式編程中的實(shí)現(xiàn),備忘錄模式數(shù)據(jù)的存儲(chǔ)過(guò)程中應(yīng)當(dāng)注意淺拷貝和深拷貝的問(wèn)題,需要的朋友可以參考下2016-04-04