java+如何实现开箱即用的敏感词控台服务?

sensitive-word-admin是一个基于sensitive-word的敏感词管理服务,提供CRUD操作和API接口。服务包括敏感词配置、类型区分(禁止和允许)、状态控制。通过数据库存储敏感词,支持实时生效的配置变更。使用SpringBoot和Mybatis-Plus构建,对外提供contains、findAll和replace等API接口进行敏感词检测和替换。
摘要由CSDN通过智能技术生成

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":"**做**"} 

所有的结果可以根据控台更改,实时生效。

实现原理

底层依赖

依赖 github.com/houbb/sensi… 提供的敏感词工具。

因为原来的工具只有一些最基本的功能,无法根据配置动态变化,不符合实际应用场景。

所以在原有的基础上实现了一个开箱即用的控台,并且提供了简单的 API。

对于敏感词工具本身,本篇不做介绍,推荐阅读:

敏感词使用入门介绍

技术选型

springboot

mybatis-plus

vue

基于数据库的敏感词

自定义的敏感词相关数据存储在数据库,对应的定义如下:

/**
 * 自定义敏感词
 * 
 * @author 老马啸西风
 * @since 1.1.0
 */
@Component
public class MyDdWordDeny implements IWordDeny {@Autowiredprivate WordService wordService;@Overridepublic 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>() {@Overridepublic String handle(Word word) {return word.getWord();}});}

} 

/**
 * 自定义白名单
 * 
 * @author 老马啸西风
 * @since 1.1.0
 */
@Component
public class MyDdWordAllow implements IWordAllow {@Autowiredprivate WordService wordService;@Overridepublic 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>() {@Overridepublic String handle(Word word) {return word.getWord();}});}

} 

敏感词引导类初始化

对应的敏感类初始化也比较简单,我们在系统默认的基础上,添加上自定义的数据。

@Configuration
public class SensitiveWordConfig {@Autowiredprivate MyDdWordAllow myDdWordAllow;@Autowiredprivate MyDdWordDeny myDdWordDeny;/** * 初始化引导类 * @return 初始化引导类 * @since 1.0.0 */@Beanpublic 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 {@Autowiredprivate WordService wordService;@Autowiredprivate SensitiveWordBs sensitiveWordBs;/*** 首页*/@RequestMapping("/index")public String index() {return "word/index";}/*** 添加元素* @param entity 实体* @return 结果*/@RequestMapping("/add")@ResponseBodypublic BaseResp add(@RequestBody final Word entity) {wordService.insert(entity);refreshSensitiveWord();return RespUtil.success();}/*** 编辑* @param entity 实体* @return 结果*/@RequestMapping("/edit")@ResponseBodypublic BaseResp edit(final Word entity) {wordService.updateById(entity);refreshSensitiveWord();return RespUtil.success();}/*** 删除* @param id 实体* @return 结果*/@RequestMapping("/remove/{id}")@ResponseBodypublic 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 {@Autowiredprivate 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);}

} 

如果实际我们真的对外部提供服务,肯定要比这个复杂的多,如果要考虑安全相关问题。

推荐阅读:

如何从零实现属于自己的 API 网关?

你连对外接口签名都不会知道?有时间还是要学习学习

和你一起走进对称加密算法的世界

springboot 实现拦截器的 3 种方式介绍

小结

敏感词的应用非常广泛,任何涉及到用户可以自由发言的地方,就需要考虑敏感词。

本文主要是为了演示如何基于 sensitive-word 实现一个开箱即用的敏感词服务,希望对你有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值