java 如何实现开箱即用的敏感词控台服务?
sensitive-word-admin
sensitive-word-admin 是基于 sensitive-word 实现的,
一款开箱即用的敏感词控台服务。
特性
基本的 CRUD
开箱即用的配置控台
简单易用的 API 服务
快速开始
数据库脚本
执行 mysql-5.7.sql 脚本。
核心表如下:
create table word
(
id int unsigned auto_increment comment '应用自增主键' primary key,
word varchar(128) not null comment '单词',
type varchar(8) not null comment '类型',
status char(1) not null default 'S' comment '状态',
remark varchar(64) not null comment '配置描述' default '',
operator_id varchar(64) not null default 'system' comment '操作员名称',
create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间戳',
update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间戳'
) comment '敏感词表' ENGINE=Innodb default charset=UTF8 auto_increment=1;
create unique index uk_word on word (word) comment '唯一索引';
应用启动
直接运行 Applicaiton#main() 启动应用,启动日志如下:
2021-07-20 20:56:48.200 INFO [] 6680 --- [ main] o.a.coyote.http11.Http11NioProtocol : Starting ProtocolHandler ["http-nio-8080"]
2021-07-20 20:56:48.219 INFO [] 6680 --- [ main] o.a.tomcat.util.net.NioSelectorPool : Using a shared selector for servlet write/read
2021-07-20 20:56:48.248 INFO [] 6680 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2021-07-20 20:56:48.256 INFO [] 6680 --- [ main] c.g.h.sensitive.word.admin.Application : Started Application in 14.04 seconds (JVM running for 15.82)
敏感词配置
除了 sensitive-word 本身自带的敏感词外,我们可以根据自己的业务进行配置。
类型分为两种:禁止和允许。禁止说明是敏感词,允许说明不认为是敏感词。
所有的类型,只要在状态为正常的情况下才会生效。
测试验证
contains
是否包含敏感词。
http://localhost:8080/api/sensitiveWord/contains?text=凡凡做测试
返回:
{"respCode":"0000","respMessage":"成功","result":true}
findAll
找到所有的敏感词。
http://localhost:8080/api/sensitiveWord/findAll?text=凡凡做测试
返回:
{"respCode":"0000","respMessage":"成功","total":2,"list":["凡凡","测试"]}
replace
替换对应的敏感词。
http://localhost:8080/api/sensitiveWord/replace?text=凡凡做测试
返回:
{"respCode":"0000","respMessage":"成功","result":"**做**"}
所有的结果可以根据控台更改,实时生效。
实现原理
底层依赖
依赖 https://github.com/houbb/sensitive-word 提供的敏感词工具。
因为原来的工具只有一些最基本的功能,无法根据配置动态变化,不符合实际应用场景。
所以在原有的基础上实现了一个开箱即用的控台,并且提供了简单的 API。
对于敏感词工具本身,本篇不做介绍,推荐阅读:
技术选型
springboot
mybatis-plus
vue
基于数据库的敏感词
自定义的敏感词相关数据存储在数据库,对应的定义如下:
/**
* 自定义敏感词
*
* @author 老马啸西风
* @since 1.1.0
*/
@Component
public class MyDdWordDeny implements IWordDeny {
@Autowired
private WordService wordService;
@Override
public List<String> deny() {
Wrapper<Word> wordWrapper = new EntityWrapper<>();
wordWrapper.eq("type", WordTypeEnum.DENY.getCode());
wordWrapper.eq("status", WordStatusEnum.S.getCode());
List<Word> wordList = wordService.selectList(wordWrapper);
return CollectionUtil.toList(wordList, new IHandler<Word, String>() {
@Override
public String handle(Word word) {
return word.getWord();
}
});
}
}
和
/**
* 自定义白名单
*
* @author 老马啸西风
* @since 1.1.0
*/
@Component
public class MyDdWordAllow implements IWordAllow {
@Autowired
private WordService wordService;
@Override
public List<String> allow() {
Wrapper<Word> wordWrapper = new EntityWrapper<>();
wordWrapper.eq("type", WordTypeEnum.ALLOW.getCode());
wordWrapper.eq("status", WordStatusEnum.S.getCode());
List<Word> wordList = wordService.selectList(wordWrapper);
return CollectionUtil.toList(wordList, new IHandler<Word, String>() {
@Override
public String handle(Word word) {
return word.getWord();
}
});
}
}
敏感词引导类初始化
对应的敏感类初始化也比较简单,我们在系统默认的基础上,添加上自定义的数据。
@Configuration
public class SensitiveWordConfig {
@Autowired
private MyDdWordAllow myDdWordAllow;
@Autowired
private MyDdWordDeny myDdWordDeny;
/**
* 初始化引导类
* @return 初始化引导类
* @since 1.0.0
*/
@Bean
public SensitiveWordBs sensitiveWordBs() {
return SensitiveWordBs.newInstance()
.wordAllow(WordAllows.chains(WordAllows.system(), myDdWordAllow))
.wordDeny(WordDenys.chains(WordDenys.system(), myDdWordDeny))
.ignoreRepeat(false)
// 各种其他配置
.init();
}
}
配置变更及敏感词刷新
每一次敏感词配置发生变更的时候,我们都主动刷新一下敏感词词典信息。
/**
* <p>
* 敏感词表 前端控制器
* </p>
*
* @author 老马啸西风
* @since 2021-07-07
*/
@Controller
@RequestMapping("/word")
@TraceId
@AutoLog
public class WordController {
@Autowired
private WordService wordService;
@Autowired
private SensitiveWordBs sensitiveWordBs;
/**
* 首页
*/
@RequestMapping("/index")
public String index() {
return "word/index";
}
/**
* 添加元素
* @param entity 实体
* @return 结果
*/
@RequestMapping("/add")
@ResponseBody
public BaseResp add(@RequestBody final Word entity) {
wordService.insert(entity);
refreshSensitiveWord();
return RespUtil.success();
}
/**
* 编辑
* @param entity 实体
* @return 结果
*/
@RequestMapping("/edit")
@ResponseBody
public BaseResp edit(final Word entity) {
wordService.updateById(entity);
refreshSensitiveWord();
return RespUtil.success();
}
/**
* 删除
* @param id 实体
* @return 结果
*/
@RequestMapping("/remove/{id}")
@ResponseBody
public BaseResp remove(@PathVariable final Integer id) {
wordService.deleteById(id);
refreshSensitiveWord();
return RespUtil.success();
}
/**
* 刷新敏感詞
*
* 可以优化为异步,甚至批量。
* @since 1.1.0
*/
private void refreshSensitiveWord() {
sensitiveWordBs.init();
}
}
提供对外接口
这里提供的接口仅当做演示:
/**
* api 服务
* @author 老马啸西风
* @since 1.1.0
*/
@RestController
@RequestMapping("/api/sensitiveWord/")
@AutoLog
@TraceId
public class ApiSensitiveWordController {
@Autowired
private SensitiveWordBs sensitiveWordBs;
/**
* 是否包含敏感词
*
* @param text 文本
* @return 结果
*/
@RequestMapping("/contains")
public BaseResp contains(@RequestParam("text") String text) {
boolean contains = sensitiveWordBs.contains(text);
return RespUtil.of(contains);
}
/**
* 获取所有的敏感词
* @param text 文本
* @return 结果
*/
@RequestMapping("/findAll")
public BaseResp findAll(@RequestParam("text") String text) {
List<String> results = sensitiveWordBs.findAll(text);
return RespUtil.of(results);
}
/**
* 获取替换后的结果
*
* @param text 文本
* @return 结果
*/
@RequestMapping("/replace")
public BaseResp replace(@RequestParam("text") String text) {
String results = sensitiveWordBs.replace(text);
return RespUtil.of(results);
}
}
如果实际我们真的对外部提供服务,肯定要比这个复杂的多,如果要考虑安全相关问题。
推荐阅读:
小结
敏感词的应用非常广泛,任何涉及到用户可以自由发言的地方,就需要考虑敏感词。
本文主要是为了演示如何基于 sensitive-word 实现一个开箱即用的敏感词服务,希望对你有所帮助。
我是老马,期待与你的下次重逢。
备注:涉及的代码较多,文中做了简化。若你对源码感兴趣,可以關註{老马啸西风},後臺回復{敏感词}即可获得。
java 如何实现开箱即用的敏感词控台服务?的更多相关文章
- 使用DFA算法对敏感词进行过滤
项目目录结构如下: 其中resources资源目录中: stopwd.txt :停顿词,匹配时间直接过滤. wd.txt:敏感词库. 1.WordFilter敏感词过滤类: package com.s ...
- java控台输入
import java.util.Scanner;//访问util包的Scanner(控台输入) public class HelloWorld {public static void main(St ...
- java实现敏感词过滤(DFA算法)
小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxo ...
- Java实现敏感词过滤
敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...
- java敏感词过滤
敏感词过滤在网站开发必不可少.一般用DFA,这种比较好的算法实现的. 参考链接:http://cmsblogs.com/?p=1031 一个比较好的代码实现: import java.io.IOExc ...
- Java实现敏感词过滤(转)
敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...
- Java 敏感词过滤,Java 敏感词替换,Java 敏感词工具类
Java 敏感词过滤,Java 敏感词替换,Java 敏感词工具类 =========================== ©Copyright 蕃薯耀 2017年9月25日 http://www ...
- java实现文章敏感词过滤检测
SensitivewordFilter.java import java.util.HashSet; import java.util.Iterator; import java.util.Map; ...
- Java实现敏感词过滤 - IKAnalyzer中文分词工具
IKAnalyzer 是一个开源的,基于java语言开发的轻量级的中文分词工具包. 官网: https://code.google.com/archive/p/ik-analyzer/ 本用例借助 I ...
- Java实现敏感词过滤 - DFA算法
Java实现DFA算法进行敏感词过滤 封装工具类如下: 使用前需对敏感词库进行初始化: SensitiveWordUtil.init(sensitiveWordSet); package cn.swf ...
随机推荐
- Linux 查看office文件及pdf文件
1.查看pdf文件 evince PdfFile_name 查看office文件 openoffice.org 文件名 & // 打开或者编辑.doc.odt等文本文档命令 openoffic ...
- IDEA中无法调出中文输入法?
参考链接:idea写代码时无法切换到中文输入
- 【转】C语言表驱动法编程实践
来源:C语言表驱动法编程实践(精华帖,建议收藏并实践) (qq.com) 数据压倒一切.如果选择了正确的数据结构并把一切组织的井井有条,正确的算法就不言自明.编程的核心是数据结构,而不是算法. --R ...
- (保姆级)服务器-Zabbix6.0使用Python脚本实现带图片的邮箱的报警
前言 近期在琢磨Zabbix邮箱报警的功能,但是网上的教程通常是4.0或5.0版本Zabbix,并使用Python2.7环境,运行在新版本Zabbix6.0上有颇多问题,为此我基于原先教程修改基于Za ...
- [转帖]clickHouse单机模式安装部署(RPM安装)
关于版本和系统的选择 操作系统:Centos-7 ClickHouse: rpm 在安装,20.x 安装前的准备 CentOS7 打开文件数限 在 /etc/security/limits.conf ...
- 人大金仓学习之二_ksh和kddm的学习
人大金仓学习之二_ksh和kddm的学习 摘要 承接上一篇文章 主要是这里总结一下ksh相关的文档. 这里学习了很多文档: https://help.kingbase.com.cn/v8/perfor ...
- Nginx 发布 Docker 运行日志的方法
背景 公司这边想进行容器化负载均衡部署. 脚本很简单, 已经实现了, 但是发现我这边没有ELK也没有LOKI 又不太像切入到容器内部进行 获取日志信息. 所以我这边想了一个别的招来动态刷新日志. 思路 ...
- SAP FICO 前台财务过账、预制功能分开
最近遇到一个变态要求,FB01 等涉及过账功能 要求根据'权限'判断用户是否有过账的功能.以下实现会有遗漏场景: 实现:hide 'SAVE'按钮 (ok_code = 'BU'). 根据状态栏设置' ...
- 强大的AWS lambda
AWS强大的lambda 自从几年前换工作后,我所参与的项目一直都是基于AWS云服务的架构,我慢慢对serverless的相关基础建设有了一定了解和实践经验.其中lambda是我心中最强大的serve ...
- 从零开始配置vim(28)——代码的编译、运行与调试
在前面几个章节,我们逐渐为 Vim 配置了语法高亮.代码的跳转和自动补全功能.现在的 Vim 已经可以作为代码编辑器来使用了.但是想将它作为日常发开的主力编辑器来用还需要很长一段路要走,其中一个就是要 ...