最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot 框架下高效敏感詞過(guò)濾功能的實(shí)現(xiàn)方案

 更新時(shí)間:2026年01月21日 10:26:47   作者:Yaml墨韻  
內(nèi)容安全審核是一個(gè)非常重要的功能,本文將詳細(xì)介紹在SpringBoot項(xiàng)目中實(shí)現(xiàn)一個(gè)功能完善的敏感詞過(guò)濾系統(tǒng),使用DFA算法實(shí)現(xiàn)高效的敏感詞匹配,結(jié)合Redis實(shí)現(xiàn)敏感詞的持久化存儲(chǔ),提供完整的RESTAPI接口,支持敏感詞的動(dòng)態(tài)添加和更新,感興趣的可以了解一下

在實(shí)際項(xiàng)目開發(fā)中,內(nèi)容安全審核是一個(gè)非常重要的功能。本文將詳細(xì)介紹如何在SpringBoot項(xiàng)目中實(shí)現(xiàn)一個(gè)功能完善的敏感詞過(guò)濾系統(tǒng)。我們將從項(xiàng)目搭建、核心代碼實(shí)現(xiàn)到實(shí)際應(yīng)用場(chǎng)景逐步展開講解。

一、項(xiàng)目準(zhǔn)備

首先,創(chuàng)建一個(gè)SpringBoot項(xiàng)目,在pom.xml中添加必要的依賴:

  • Spring Web:用于構(gòu)建 RESTful API。
  • Lombok:簡(jiǎn)化 JavaBean 的編寫,這里主要用于日志記錄注解。
  • Apache Commons Lang3:提供了一些常用的工具類,如字符串處理等。
  • Spring Data Redis:如果要將敏感詞存儲(chǔ)在 Redis 中,用于操作 Redis 數(shù)據(jù)庫(kù)。
    <dependencies>
        <!-- SpringBoot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Redis依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Commons Lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>

二、核心代碼實(shí)現(xiàn)

1、敏感詞過(guò)濾器實(shí)現(xiàn)類

@Component
@Slf4j
public class SensitiveWordFilter {

    // 敏感詞字典樹,用于存儲(chǔ)敏感詞
    private Map<Character, Map> sensitiveWordMap;

    // 最小匹配規(guī)則,表示找到第一個(gè)匹配到的敏感詞就返回
    public static final int MATCH_TYPE_MIN = 1;

    // 最大匹配規(guī)則,表示找到最長(zhǎng)的匹配敏感詞再返回
    public static final int MATCH_TYPE_MAX = 2;

    // 注入Redis模板,用于從Redis中加載敏感詞
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 初始化敏感詞過(guò)濾器,包括從Redis加載敏感詞
     */
    @PostConstruct
    public void init() {
        sensitiveWordMap = new HashMap<>();
        // 從Redis加載敏感詞并初始化字典樹
        loadSensitiveWordsFromRedis();
    }

    /**
     * 從Redis加載敏感詞并初始化到字典樹中
     */
    private void loadSensitiveWordsFromRedis() {
        try {
            // 從Redis的sensitive_words集合中獲取所有敏感詞
            Set<String> words = stringRedisTemplate.opsForSet().members("sensitive_words");
            if (words != null) {
                // 遍歷敏感詞集合,將每個(gè)敏感詞添加到字典樹中
                words.forEach(this::addWordToMap);
            }
        } catch (Exception e) {
            // 記錄加載敏感詞失敗日志
            log.error("Failed to load sensitive words from Redis", e);
        }
    }

    /**
     * 將敏感詞添加到字典樹中
     * @param word 要添加的敏感詞
     */
    public void addWordToMap(String word) {
        Map<Character, Map> currentMap = sensitiveWordMap;
        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);
            Map<Character, Map> subMap = currentMap.get(c);

            if (subMap == null) {
                // 如果當(dāng)前字符不存在于字典樹中,則創(chuàng)建新的節(jié)點(diǎn)
                subMap = new HashMap<>();
                currentMap.put(c, subMap);
            }

            currentMap = subMap;

            // 如果是敏感詞的最后一個(gè)字符,則標(biāo)記為敏感詞結(jié)束
            if (i == word.length() - 1) {
                currentMap.put('$', null);
            }
        }
    }

    /**
     * 檢查文本中是否包含敏感詞(最小匹配規(guī)則)
     * @param text 要檢查的文本
     * @return 如果包含敏感詞則返回true,否則返回false
     */
    public boolean containsSensitiveWord(String text) {
        if (StringUtils.isBlank(text)) {
            return false;
        }

        // 遍歷文本中的每個(gè)字符,檢查是否存在敏感詞
        for (int i = 0; i < text.length(); i++) {
            int length = checkSensitiveWord(text, i, MATCH_TYPE_MIN);
            if (length > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 在文本中找到所有敏感詞(最大匹配規(guī)則)
     * @param text 要查找的文本
     * @return 包含所有找到的敏感詞的集合
     */
    public Set<String> findSensitiveWords(String text) {
        Set<String> sensitiveWords = new HashSet<>();
        if (StringUtils.isBlank(text)) {
            return sensitiveWords;
        }

        // 遍歷文本中的每個(gè)字符,查找敏感詞并添加到集合中
        for (int i = 0; i < text.length(); i++) {
            int length = checkSensitiveWord(text, i, MATCH_TYPE_MAX);
            if (length > 0) {
                sensitiveWords.add(text.substring(i, i + length));
                // 更新索引以跳過(guò)已找到的敏感詞
                i = i + length - 1;
            }
        }
        return sensitiveWords;
    }

    /**
     * 過(guò)濾文本中的敏感詞,用'*'替換
     * @param text 要過(guò)濾的文本
     * @return 過(guò)濾后的文本
     */
    public String filter(String text) {
        if (StringUtils.isBlank(text)) {
            return text;
        }

        StringBuilder result = new StringBuilder(text);
        Set<String> words = findSensitiveWords(text);

        // 遍歷找到的敏感詞,用'*'替換
        for (String word : words) {
            int index = result.indexOf(word);
            while (index != -1) {
                for (int i = index; i < index + word.length(); i++) {
                    result.setCharAt(i, '*');
                }
                index = result.indexOf(word, index + 1);
            }
        }

        return result.toString();
    }

    /**
     * 檢查文本中從指定索引開始的子串是否包含敏感詞
     * @param text 要檢查的文本
     * @param beginIndex 開始檢查的索引
     * @param matchType 匹配規(guī)則(最小匹配或最大匹配)
     * @return 找到的敏感詞長(zhǎng)度,如果沒(méi)有找到則返回0
     */
    private int checkSensitiveWord(String text, int beginIndex, int matchType) {
        Map<Character, Map> currentMap = sensitiveWordMap;
        int wordLength = 0;
        int maxLength = 0;

        // 從指定索引開始遍歷文本字符
        for (int i = beginIndex; i < text.length(); i++) {
            char c = text.charAt(i);
            currentMap = currentMap.get(c);

            if (currentMap == null) {
                break;
            }

            wordLength++;

            // 如果當(dāng)前節(jié)點(diǎn)標(biāo)記為敏感詞結(jié)束
            if (currentMap.containsKey('$')) {
                if (matchType == MATCH_TYPE_MIN) {
                    // 最小匹配規(guī)則,返回當(dāng)前敏感詞長(zhǎng)度
                    return wordLength;
                } else {
                    // 最大匹配規(guī)則,記錄當(dāng)前敏感詞長(zhǎng)度,繼續(xù)檢查是否還有更長(zhǎng)的敏感詞
                    maxLength = wordLength;
                }
            }
        }

        // 最大匹配規(guī)則下返回最長(zhǎng)敏感詞長(zhǎng)度
        return maxLength;
    }
}

2. 配置類

import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.context.annotation.Bean;

@Configuration
public class RedisConfig {

    /**
     * 創(chuàng)建并配置StringRedisTemplate的Bean實(shí)例
     *
     * @param connectionFactory Redis連接工廠實(shí)例,用于創(chuàng)建與Redis服務(wù)器的連接
     * @return 配置好的StringRedisTemplate實(shí)例,可用于在Spring應(yīng)用中方便地操作Redis中的字符串?dāng)?shù)據(jù)類型
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(connectionFactory);
        return template;
    }
}

3. Controller實(shí)現(xiàn)

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Resource;
import java.util.Set;

@RestController
@RequestMapping("/api/sensitive")
@Slf4j
public class SensitiveWordController {

    @Resource
    private SensitiveWordFilter sensitiveWordFilter;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 處理添加敏感詞的請(qǐng)求
     *
     * @param word 要添加的敏感詞內(nèi)容,通過(guò)請(qǐng)求體傳入
     * @return 返回添加結(jié)果的響應(yīng)實(shí)體,添加成功則返回狀態(tài)碼200及"添加成功"消息,添加失敗則返回狀態(tài)碼500及"添加失敗"消息
     */
    @PostMapping("/word")
    public ResponseEntity<String> addSensitiveWord(@RequestBody String word) {
        try {
            // 將敏感詞添加到Redis的集合中
            stringRedisTemplate.opsForSet().add("sensitive_words", word);
            // 將敏感詞添加到敏感詞過(guò)濾器的字典樹中
            sensitiveWordFilter.addWordToMap(word);
            return ResponseEntity.ok("添加成功");
        } catch (Exception e) {
            log.error("添加敏感詞失敗", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("添加失敗");
        }
    }

    /**
     * 處理檢查文本是否包含敏感詞的請(qǐng)求
     *
     * @param text 要檢查的文本內(nèi)容,通過(guò)請(qǐng)求體傳入
     * @return 返回檢查結(jié)果的響應(yīng)實(shí)體,包含文本是否包含敏感詞的布爾值,狀態(tài)碼為200
     */
    @PostMapping("/check")
    public ResponseEntity<Boolean> checkText(@RequestBody String text) {
        return ResponseEntity.ok(sensitiveWordFilter.containsSensitiveWord(text));
    }

    /**
     * 處理過(guò)濾文本中敏感詞的請(qǐng)求
     *
     * @param text 要過(guò)濾的文本內(nèi)容,通過(guò)請(qǐng)求體傳入
     * @return 返回過(guò)濾后的文本內(nèi)容的響應(yīng)實(shí)體,狀態(tài)碼為200
     */
    @PostMapping("/filter")
    public ResponseEntity<String> filterText(@RequestBody String text) {
        return ResponseEntity.ok(sensitiveWordFilter.filter(text));
    }

    /**
     * 處理獲取文本中所有敏感詞的請(qǐng)求
     *
     * @param text 要獲取敏感詞的文本內(nèi)容,通過(guò)請(qǐng)求體傳入
     * @return 返回包含文本中所有敏感詞的集合的響應(yīng)實(shí)體,狀態(tài)碼為200
     */
    @PostMapping("/find")
    public ResponseEntity<Set<String>> findSensitiveWords(@RequestBody String text) {
        return ResponseEntity.ok(sensitiveWordFilter.findSensitiveWords(text));
    }
}

三、配置文件

application.yml中添加Redis配置:

spring:  
    redis:    
        host: localhost    
        port: 6379    
        database: 0    
        timeout: 10000

四、使用示例

1. 添加敏感詞

curl -X POST http://localhost:8080/api/sensitive/word -d "敏感詞1"

2. 檢查文本

curl -X POST http://localhost:8080/api/sensitive/check -d "這是一段包含敏感詞1的文本"

3. 過(guò)濾文本

curl -X POST http://localhost:8080/api/sensitive/filter -d "這是一段包含敏感詞1的文本"

五、性能優(yōu)化建議

1、Redis優(yōu)化

使用Redis集群提高可用性

通過(guò)Redis Cluster模式,將數(shù)據(jù)分散存儲(chǔ)在多個(gè)節(jié)點(diǎn)上,實(shí)現(xiàn)水平擴(kuò)展和負(fù)載均衡。這不僅可以提高并發(fā)處理能力,還能在主節(jié)點(diǎn)故障時(shí),通過(guò)自動(dòng)的故障轉(zhuǎn)移機(jī)制保證系統(tǒng)的可用性。

實(shí)現(xiàn)Redis緩存預(yù)熱

在系統(tǒng)上線前或低峰期,提前將熱點(diǎn)數(shù)據(jù)加載到Redis緩存中,以減少用戶請(qǐng)求時(shí)的數(shù)據(jù)庫(kù)查詢壓力,提高響應(yīng)速度。可以通過(guò)分析歷史訪問(wèn)記錄,確定熱點(diǎn)數(shù)據(jù),并使用腳本程序觸發(fā)數(shù)據(jù)預(yù)熱過(guò)程。

添加Redis連接池配置

使用連接池來(lái)管理Redis的連接,可以減少頻繁創(chuàng)建和關(guān)閉連接的開銷,提高連接復(fù)用率。配置連接池時(shí),需要根據(jù)實(shí)際業(yè)務(wù)需求和服務(wù)器資源情況,合理設(shè)置最大連接數(shù)、最大空閑連接數(shù)等參數(shù)。

并發(fā)處理

Redis本身支持高并發(fā)處理,但可以通過(guò)進(jìn)一步優(yōu)化配置和使用相關(guān)技術(shù)來(lái)提高并發(fā)性能。例如,使用Redis的Pipeline功能將多個(gè)命令打包并一次性執(zhí)行,減少網(wǎng)絡(luò)通信的開銷;使用分布式鎖和樂(lè)觀鎖等技術(shù)來(lái)協(xié)調(diào)多個(gè)客戶端之間的并發(fā)訪問(wèn)。

使用本地緩存減少Redis訪問(wèn)

在應(yīng)用服務(wù)器本地設(shè)置一層緩存(如Guava Cache或Caffeine等),用于存儲(chǔ)一些訪問(wèn)頻率高且變化不頻繁的數(shù)據(jù)。當(dāng)數(shù)據(jù)在本地緩存中命中時(shí),可以直接返回結(jié)果,減少對(duì)Redis的訪問(wèn)壓力。

2、功能擴(kuò)展

支持敏感詞分級(jí)

根據(jù)敏感詞的嚴(yán)重程度或影響范圍,將其分為不同的級(jí)別。在過(guò)濾敏感詞時(shí),可以根據(jù)級(jí)別采取不同的處理措施(如替換、刪除或警告等)。

實(shí)現(xiàn)自定義替換規(guī)則

提供一種機(jī)制,允許用戶根據(jù)自己的需求定義敏感詞的替換規(guī)則。例如,可以將某些敏感詞替換為指定的占位符或符號(hào),以避免直接顯示敏感內(nèi)容。

添加白名單機(jī)制優(yōu)化

對(duì)于一些特定的用戶或內(nèi)容,可以將其添加到白名單中,以允許其包含敏感詞而不被過(guò)濾。這可以用于一些特殊的場(chǎng)景,如內(nèi)部測(cè)試或特定用戶的權(quán)限管理。

實(shí)現(xiàn)敏感詞的定時(shí)更新機(jī)制

通過(guò)設(shè)置定時(shí)任務(wù)或使用Redis的發(fā)布訂閱系統(tǒng),定期從外部數(shù)據(jù)源(如數(shù)據(jù)庫(kù)、文件或遠(yuǎn)程服務(wù)器等)獲取最新的敏感詞列表,并更新到Redis緩存中。這可以確保敏感詞過(guò)濾的準(zhǔn)確性和及時(shí)性。

添加并發(fā)控制

在處理敏感詞過(guò)濾等操作時(shí),需要考慮并發(fā)控制的問(wèn)題。可以使用Redis的分布式鎖或其他并發(fā)控制技術(shù)來(lái)確保多個(gè)客戶端之間不會(huì)同時(shí)修改敏感詞列表或緩存數(shù)據(jù),從而避免數(shù)據(jù)不一致的問(wèn)題。

六、總結(jié)

本文介紹了如何在SpringBoot中實(shí)現(xiàn)敏感詞過(guò)濾功能,主要特點(diǎn)包括:

  • 使用DFA算法實(shí)現(xiàn)高效的敏感詞匹配
  • 結(jié)合Redis實(shí)現(xiàn)敏感詞的持久化存儲(chǔ)
  • 提供完整的REST API接口
  • 支持敏感詞的動(dòng)態(tài)添加和更新
  • 考慮了實(shí)際應(yīng)用場(chǎng)景和性能優(yōu)化

到此這篇關(guān)于SpringBoot 框架下高效敏感詞過(guò)濾功能的實(shí)現(xiàn)方案的文章就介紹到這了,更多相關(guān)SpringBoot高效敏感詞過(guò)濾功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java的面向?qū)ο蠛兔嫦蜻^(guò)程

    詳解Java的面向?qū)ο蠛兔嫦蜻^(guò)程

    我們知道,Java是面向?qū)ο蟮木幊陶Z(yǔ)言,但是至今仍有不少同學(xué)還不太懂”面向?qū)ο蟆暗拇_切含義,今天這篇文章就帶大家真正地認(rèn)識(shí)面向?qū)ο?,感興趣的同學(xué)可以跟著小編一起來(lái)學(xué)習(xí)
    2023-05-05
  • SpringBoot中實(shí)現(xiàn)定時(shí)任務(wù)的幾種方式

    SpringBoot中實(shí)現(xiàn)定時(shí)任務(wù)的幾種方式

    定時(shí)任務(wù)在我們項(xiàng)目開發(fā)中也是很重要的,對(duì)于某些場(chǎng)景必須要用定時(shí)任務(wù)?,如定時(shí)發(fā)送郵件啊,定時(shí)統(tǒng)計(jì)數(shù)據(jù)等,這篇文章主要講講項(xiàng)目中實(shí)現(xiàn)定時(shí)任務(wù)的幾種方式,需要的朋友可以參考下
    2023-05-05
  • SpringMVC 參數(shù)綁定意義及實(shí)現(xiàn)過(guò)程解析

    SpringMVC 參數(shù)綁定意義及實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了SpringMVC 參數(shù)綁定意義及實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請(qǐng)求的操作

    解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請(qǐng)求的操作

    這篇文章主要介紹了解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請(qǐng)求的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Java 調(diào)用天氣Webservice詳解及實(shí)例代碼

    Java 調(diào)用天氣Webservice詳解及實(shí)例代碼

    這篇文章主要介紹了Java 調(diào)用天氣Webservice詳解及實(shí)例代碼的相關(guān)資料,這里附實(shí)例代碼,使用java 調(diào)用webservice 的小應(yīng)用,需要的朋友可以參考下
    2016-11-11
  • java實(shí)現(xiàn)自動(dòng)售貨機(jī)

    java實(shí)現(xiàn)自動(dòng)售貨機(jī)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)自動(dòng)售貨機(jī),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 基于GeoTools和SpringBoot的省域駕車最快路線規(guī)劃方法

    基于GeoTools和SpringBoot的省域駕車最快路線規(guī)劃方法

    本文探討基于GeoTools與SpringBoot的省域駕車最快路線規(guī)劃方法,解決復(fù)雜路況與地理因素影響,通過(guò)天地圖API計(jì)算并存儲(chǔ)距離數(shù)據(jù),展示湖南、新疆、黑龍江等地的路線成果,為交通與經(jīng)濟(jì)影響評(píng)估提供參考,感興趣的朋友快來(lái)一起學(xué)習(xí)吧
    2025-07-07
  • Spring?IOC容器啟動(dòng)示例分析

    Spring?IOC容器啟動(dòng)示例分析

    這篇文章主要給大家介紹了Spring?IOC基于注解啟動(dòng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 一文帶你了解Java中的函數(shù)式編程

    一文帶你了解Java中的函數(shù)式編程

    函數(shù)式編程的理論基礎(chǔ)是阿隆佐·丘奇(Alonzo Church)于 1930 年代提出的 λ 演算(Lambda Calculus)。這篇文章主要為大家介紹了函數(shù)式編程的相關(guān)知識(shí),希望對(duì)大家有所幫助
    2023-04-04
  • Mybatis注解sql時(shí)出現(xiàn)的一個(gè)錯(cuò)誤及解決

    Mybatis注解sql時(shí)出現(xiàn)的一個(gè)錯(cuò)誤及解決

    這篇文章主要介紹了Mybatis注解sql時(shí)出現(xiàn)的一個(gè)錯(cuò)誤及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評(píng)論

东兴市| 奉贤区| 阳西县| 永福县| 永川市| 大安市| 缙云县| 芜湖县| 崇阳县| 郧西县| 余干县| 都匀市| 定安县| 平武县| 安徽省| 临猗县| 富民县| 蓝山县| 镇江市| 墨竹工卡县| 习水县| 平邑县| 武邑县| 慈利县| 张掖市| 监利县| 永仁县| 许昌市| 哈密市| 大石桥市| 华坪县| 东乌珠穆沁旗| 光山县| 恩平市| 余庆县| 三原县| 铜川市| 长武县| 巴塘县| 怀柔区| 义乌市|