千家信息网

SpringBoot使用前缀树过滤敏感词的方法是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章跟大家分析一下"SpringBoot使用前缀树过滤敏感词的方法是什么"。内容详细易懂,对"SpringBoot使用前缀树过滤敏感词的方法是什么"感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下
千家信息网最后更新 2026年11月01日SpringBoot使用前缀树过滤敏感词的方法是什么

这篇文章跟大家分析一下"SpringBoot使用前缀树过滤敏感词的方法是什么"。内容详细易懂,对"SpringBoot使用前缀树过滤敏感词的方法是什么"感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习"SpringBoot使用前缀树过滤敏感词的方法是什么"的知识吧。

一、前缀树

一般设计网站的时候,会有问题发布或者是内容发布的功能,这些功能的有一个很重要的点在于如何实现敏感词过滤,要不然可能会有不良信息的发布,或者发布的内容中有夹杂可能会有恶意功能的代码片段,敏感词过滤的基本的算法是前缀树算法,前缀树也就是字典树,通过前缀树匹配可以加快敏感词匹配的速度。

前缀树又称为Trie、字典树、查找树。主要特点是:查找效率高,但内存消耗大;主要应用于字符串检索、词频统计、字符串排序等。

到底什么是前缀树?前缀树的功能是如何实现的?

举一个具体的例子:若有一个字符串"xwabfabcff",敏感词为"abc"、"bf"、"be",检测字符串,若有敏感词,则将敏感词替换为"*",实现一个算法。

前缀树的特点:

1. 跟结点为空结点,没有任何字符。

2. 除了根节点以外,每个结点只有一个字符。

3. 每个结点包含的子节点不相同。 例如,root的子节点本来有两个b,但我们只保留一个

4. 在每个敏感词的末尾结点做一个标记,表示从根节点到此节点组合成的字符串是一个敏感词,中间未被标记的结点和根节点中间的字符串不构成一个敏感词。

前缀树的算法逻辑:

1. 准备:我们需要三个指针,①指针指向前缀树,默认指向根节点; ②、③指针指向要检测的字符串(同向尺距法,②从头到尾走一遍,标记敏感词的开头,③随着②而动,标记敏感词的结尾),默认指向字符串的第一个字符。我们还需要一个存放检测结果的字符串(StringBuilder)。

2. ①访问树的第一层,发现没有'x',则②、③向下走一步,并将'x'存入StringBuilder字符串里。'w' 同理。

3. 此时②、③指向'a',①访问树的第一层,发现有'a',但'a'未被标记,所以不是敏感词,则把'a'存入StringBuilder字符串。然后②不动,①、③继续向下走,直至走到被标记的结点或者不匹配时,①归位,②向下走一步,③回到此时②指向的地方。重复以上步骤。

4. 若检测到敏感词,则在StringBuilder中存储"***",并使②跳过此敏感词,②、③共同指向原来③的下一个位置。

5. ②、③走到字符串的末尾时,检测完成。最终结果为"xwa******ff"。

二、敏感词过滤器

我们再开发项目时,需要开发出一个可复用的过滤敏感词的工具,成为敏感词过滤器,以便在项目中可以复用。

开发敏感词过滤器主要有以下三个步骤:

1. 定义前缀树

2. 根据敏感词,初始化前缀树

3. 编写过滤敏感词的方法

代码实现如下:

import org.apache.commons.lang3.CharUtils;import org.apache.commons.lang3.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component; import javax.annotation.PostConstruct;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map; @Componentpublic class SensitiveFilter {     // 记录日志    private static final Logger logger = LoggerFactory.getLogger(SensitiveFilter.class);     // 替换符    private static final String REPLACEMENT = "***";     // 初始化根节点    private TrieNode rootNode = new TrieNode();     /**     * 2. 根据敏感词,初始化前缀树     */    @PostConstruct// 当容器在服务器启动时实例化此Bean,调用Bean的构造方法后,该方法就会被自动调用    public void init() {        try (                // 加载敏感词文件 sensitive-words.txt是自建的存放敏感词的文件                InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt");                // 字节流 -->  字符流 --> 字符缓冲流                BufferedReader reader = new BufferedReader(new InputStreamReader(is));        ) {            String keyword;            while((keyword = reader.readLine()) != null){                // 添加到前缀树,addKeyword为自定义的方法,将一个敏感词添加到前缀树中去                this.addKeyword(keyword);            }         } catch (IOException e) {            logger.error("加载敏感词文件失败:" + e.getMessage());        }     }     // 封装方法:将一个敏感词添加到前缀树中去    private void addKeyword(String keyword){        TrieNode tempNode = rootNode;        for (int i = 0; i < keyword.length(); i++) {            char c = keyword.charAt(i);            TrieNode subNode = tempNode.getSubNode(c);             if(subNode == null){                // 如果子节点中没有该字符,则以此字符初始化子节点,并装配到树中                subNode = new TrieNode();                tempNode.addSubNode(c,subNode);            }             // 指向字节点,进入下一层循环            tempNode = subNode;             // 设置结束标识            if(i == keyword.length() -1){                tempNode.setKeywordEnd(true);            }        }    }     /**     * 3. 检索并过滤敏感词     * @param text 待过滤的文本     * @return 过滤后的文本     */    public String filter(String text){        if(StringUtils.isBlank(text)){            return null;        }         // 指针①        TrieNode tempNode = rootNode;        // 指针②        int begin = 0;        // 指针③        int position = 0;        // 存放结果        StringBuilder sb = new StringBuilder();         while(position < text.length()){            char c = text.charAt(position);             // 跳过符号            if(isSymbol(c)){                // 若指针①处于根节点,将此符号计入结果,让指针②向下走一步                if(tempNode == rootNode){                    sb.append(c);                    begin++;                }                // 无论符号在未检测时出现还是正在检测时出现,指针③总是向下走一步                // (未检测时和指针②一起向下走一步,检测时指针②不动,指针③向下走一步)                position++;                continue;            }             // 检查下级节点            tempNode = tempNode.getSubNode(c);            if(tempNode == null){                // 以begin开头的字符串不是敏感词                sb.append(text.charAt(begin));                // 进入下一个位置                begin++;                position = begin;                // 指针①归位,重新指向根节点                tempNode = rootNode;            }else if (tempNode.isKeywordEnd()){                // 发现敏感词,将begin~position字符串替换掉                sb.append(REPLACEMENT);                // 进入下一个位置                position++;                begin = position;                // 指针①归位,重新指向跟接待你                tempNode = rootNode;            }else {                // 检查下一个字符                position++;            }        }        // 将最后一批字符计入结果:指针③比指针②先到中终点,且两者之间的字符串不是敏感词        sb.append(text.substring(begin));         return sb.toString();    }     // 封装方法:判断是否为特殊符号    private boolean isSymbol(Character c){        // 0x2E80~0x9FFF 是东亚文字范围,不予当作特殊符号看待        return !CharUtils.isAsciiAlphanumeric(c) && (c < 0x2E80 || c > 0x9FFF);    }     /**     * 1. 定义前缀树     */    private class TrieNode {         // 敏感词(关键词)结束标识        private boolean isKeywordEnd = false;         // 子节点(key是下级字符,value是下级节点)        private Map subNodes = new HashMap<>();         public boolean isKeywordEnd() {            return isKeywordEnd;        }         public void setKeywordEnd(boolean keywordEnd) {            isKeywordEnd = keywordEnd;        }         // 添加子节点        public void addSubNode(Character c, TrieNode node) {            subNodes.put(c, node);        }         // 获取子节点        public TrieNode getSubNode(Character c) {            return subNodes.get(c);        }    } }

springboot是什么

springboot一种全新的编程规范,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,SpringBoot也是一个服务于框架的框架,服务范围是简化配置文件。

关于SpringBoot使用前缀树过滤敏感词的方法是什么就分享到这里啦,希望上述内容能够让大家有所提升。如果想要学习更多知识,请大家多多留意小编的更新。谢谢大家关注一下网站!

字符 前缀 节点 指针 字符串 方法 指向 检测 结点 标记 符号 结果 内容 功能 文件 算法 开发 下级 位置 过滤器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 精品咖啡豆 互联网科技行业发展 中资互联网科技 北京互联网络科技有限公司 天下捷融互联网科技 互联网科技有限公司 翻译 西藏七维空间互联网科技有限公司 创业天下互联网科技有限公司 阿里互联网科技公司 互联网软件和科技 坤平互联网科技 四川慕妮娅互联网科技有限公司 上海京穆互联网科技有限公司 杭州披云加互联网科技有限公司 江苏互联网智能科技软件 云鲸互联网络科技有限公司 科技和互联网行业的特点 广西泛欧互联网科技有限公司 青岛互联网科技园 科技美学互联网 艺术 互联网科技园 金融科技还是互联网 成都仁贤领冠互联网科技有限公司 互联网科技公司招聘 受益于互联网科技的高速发展 千方科技属于互联网企业吗 山东子淼互联网科技有限公司 元气玛特互联网科技公司是外包吗 锡山区互联网智能科技产品供应 银行科技岗属于互联网吗
0