敏感词
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package org.xyzh.sensitive.config;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.xyzh.api.sensitive.SensitiveService;
|
||||
import org.xyzh.common.redis.service.RedisService;
|
||||
import org.xyzh.sensitive.constants.SensitiveRedisContants;
|
||||
import org.xyzh.sensitive.mapper.SensitiveMapper;
|
||||
import org.xyzh.common.dto.sensitive.TbSensitive;
|
||||
|
||||
@Component
|
||||
public class SensitiveWordInitializer implements CommandLineRunner{
|
||||
private static final Logger logger = LoggerFactory.getLogger(SensitiveWordInitializer.class);
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Autowired
|
||||
private SensitiveMapper sensitiveMapper;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
logger.info("敏感词初始化");
|
||||
// 数据库读取吸入redis
|
||||
List<TbSensitive> list = sensitiveMapper.selectAll();
|
||||
Set<String> allowSet = new HashSet<>();
|
||||
Set<String> denySet = new HashSet<>();
|
||||
list.stream().forEach(item->{
|
||||
if (item.getType().equals("allow")) {
|
||||
allowSet.add(item.getWord());
|
||||
}else {
|
||||
denySet.add(item.getWord());
|
||||
}
|
||||
});
|
||||
redisService.sAdd(SensitiveRedisContants.SENSITIVE_WORD_ALLOW, allowSet);
|
||||
redisService.sAdd(SensitiveRedisContants.SENSITIVE_WORD_DENY, denySet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.xyzh.sensitive.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.xyzh.sensitive.word.DynamicAllowWord;
|
||||
import org.xyzh.sensitive.word.DynamicDenyWord;
|
||||
|
||||
import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
|
||||
import com.github.houbb.sensitive.word.support.allow.WordAllows;
|
||||
|
||||
@Configuration
|
||||
public class SpringSensitiveWordConfig {
|
||||
|
||||
@Autowired
|
||||
private DynamicAllowWord dynamicAllowWord;
|
||||
|
||||
@Autowired
|
||||
private DynamicDenyWord dynamicDenyWord;
|
||||
/**
|
||||
* 初始化引导类
|
||||
* @return 初始化引导类
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Bean
|
||||
public SensitiveWordBs sensitiveWordBs() {
|
||||
SensitiveWordBs sensitiveWordBs = SensitiveWordBs.newInstance()
|
||||
.wordAllow(WordAllows.chains(WordAllows.defaults(), dynamicAllowWord))
|
||||
.wordDeny(dynamicDenyWord)
|
||||
// 各种其他配置
|
||||
.init();
|
||||
|
||||
return sensitiveWordBs;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.xyzh.sensitive.constants;
|
||||
|
||||
public class SensitiveRedisContants {
|
||||
public static final String SENSITIVE_WORD_ALLOW = "sensitive:word:allow";
|
||||
public static final String SENSITIVE_WORD_DENY = "sensitive:word:deny";
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.xyzh.sensitive.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.xyzh.common.dto.sensitive.TbSensitive;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface SensitiveMapper extends BaseMapper<TbSensitive> {
|
||||
|
||||
public List<TbSensitive> selectAll();
|
||||
|
||||
public Integer addSensitiveWord(TbSensitive tbSensitive);
|
||||
|
||||
public Integer deleteSensitiveWord(TbSensitive tbSensitive);
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package org.xyzh.sensitive.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.xyzh.api.sensitive.SensitiveService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.dto.sensitive.TbSensitive;
|
||||
import org.xyzh.common.redis.service.RedisService;
|
||||
import org.xyzh.sensitive.constants.SensitiveRedisContants;
|
||||
import org.xyzh.sensitive.mapper.SensitiveMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
|
||||
|
||||
@Service
|
||||
public class SensitiveServiceImpl implements SensitiveService{
|
||||
|
||||
@Autowired
|
||||
private SensitiveMapper sensitiveMapper;
|
||||
|
||||
@Autowired
|
||||
private SensitiveWordHelper sensitiveWordHelper;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public ResultDomain<Boolean> addSensitiveWord(TbSensitive tbSensitive) {
|
||||
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
|
||||
String word = tbSensitive.getWord();
|
||||
String type = tbSensitive.getType();
|
||||
|
||||
// 第一次检查:Redis中是否已存在
|
||||
String redisKey = "allow".equals(type) ? SensitiveRedisContants.SENSITIVE_WORD_ALLOW : SensitiveRedisContants.SENSITIVE_WORD_DENY;
|
||||
if (redisService.sMembers(redisKey).contains(word)) {
|
||||
resultDomain.fail("敏感词已存在");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
// 加锁
|
||||
synchronized (this) {
|
||||
// 第二次检查:再次确认Redis中是否已存在
|
||||
if (redisService.sMembers(redisKey).contains(word)) {
|
||||
resultDomain.fail("敏感词已存在");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
// 执行数据库插入
|
||||
int i = sensitiveMapper.addSensitiveWord(tbSensitive);
|
||||
if (i > 0) {
|
||||
// 同步到Redis
|
||||
redisService.sAdd(redisKey, word);
|
||||
resultDomain.success("添加敏感词成功", true);
|
||||
} else {
|
||||
resultDomain.fail("添加敏感词失败");
|
||||
}
|
||||
}
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Boolean> deleteSensitiveWord(TbSensitive tbSensitive) {
|
||||
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
|
||||
String word = tbSensitive.getWord();
|
||||
String type = tbSensitive.getType();
|
||||
|
||||
// 第一次检查:Redis中是否存在
|
||||
String redisKey = "allow".equals(type) ? SensitiveRedisContants.SENSITIVE_WORD_ALLOW : SensitiveRedisContants.SENSITIVE_WORD_DENY;
|
||||
if (!redisService.sMembers(redisKey).contains(word)) {
|
||||
resultDomain.fail("敏感词不存在");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
// 加锁
|
||||
synchronized (this) {
|
||||
// 第二次检查:再次确认Redis中是否存在
|
||||
if (!redisService.sMembers(redisKey).contains(word)) {
|
||||
resultDomain.fail("敏感词不存在");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
// 执行数据库删除
|
||||
int i = sensitiveMapper.deleteSensitiveWord(tbSensitive);
|
||||
if (i > 0) {
|
||||
// 从Redis中移除
|
||||
redisService.sRemove(redisKey, word);
|
||||
resultDomain.success("删除敏感词成功", true);
|
||||
} else {
|
||||
resultDomain.fail("删除敏感词失败");
|
||||
}
|
||||
}
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Boolean> judgeSensitive(String text) {
|
||||
ResultDomain<Boolean> resultDomain = new ResultDomain<>();
|
||||
|
||||
boolean containsSensitive = sensitiveWordHelper.contains(text);
|
||||
resultDomain.success("敏感词检测完成", containsSensitive);
|
||||
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.xyzh.sensitive.word;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.xyzh.common.redis.service.RedisService;
|
||||
import org.xyzh.sensitive.constants.SensitiveRedisContants;
|
||||
|
||||
import com.github.houbb.sensitive.word.api.IWordAllow;
|
||||
|
||||
@Component
|
||||
public class DynamicAllowWord implements IWordAllow {
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public List<String> allow() {
|
||||
Set<Object> members = redisService.sMembers(SensitiveRedisContants.SENSITIVE_WORD_ALLOW);
|
||||
if (members == null || members.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> list = new ArrayList<>(members.size());
|
||||
for (Object o : members) {
|
||||
if (o != null) {
|
||||
list.add(String.valueOf(o));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.xyzh.sensitive.word;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.xyzh.common.redis.service.RedisService;
|
||||
import org.xyzh.sensitive.constants.SensitiveRedisContants;
|
||||
|
||||
import com.github.houbb.sensitive.word.api.IWordDeny;
|
||||
|
||||
@Component
|
||||
public class DynamicDenyWord implements IWordDeny {
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public List<String> deny() {
|
||||
Set<Object> members = redisService.sMembers(SensitiveRedisContants.SENSITIVE_WORD_DENY);
|
||||
if (members == null || members.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> list = new ArrayList<>(members.size());
|
||||
for (Object o : members) {
|
||||
if (o != null) {
|
||||
list.add(String.valueOf(o));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.xyzh.sensitive.mapper.SensitiveMapper">
|
||||
<resultMap id="BaseMap" resultType="org.xyzh.common.dto.sensitive.TbSensitive">
|
||||
<id column="id" property="id"/>
|
||||
<result column="word" property="word"/>
|
||||
<result column="type" property="type"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, word, type
|
||||
</sql>
|
||||
|
||||
<select id="selectAll" resultMap="BaseMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM tb_sensitive
|
||||
</select>
|
||||
|
||||
<insert id="addSensitiveWord" parameterType="org.xyzh.common.dto.sensitive.TbSensitive" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
|
||||
INSERT INTO tb_sensitive (word, type)
|
||||
VALUES (#{word}, #{type})
|
||||
</insert>
|
||||
|
||||
<delete id="deleteSensitiveWord" parameterType="org.xyzh.common.dto.sensitive.TbSensitive">
|
||||
DELETE FROM tb_sensitive
|
||||
WHERE word = #{word}
|
||||
<if test="type != null and type != ''">
|
||||
AND type = #{type}
|
||||
</if>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,12 @@
|
||||
生日快乐
|
||||
曹操
|
||||
幸运
|
||||
幸运儿
|
||||
17年前
|
||||
1条
|
||||
1梯两户
|
||||
1比1
|
||||
年检
|
||||
幸存
|
||||
恶搞
|
||||
游戏机
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fuck
|
||||
duck
|
||||
shit
|
||||
chicken
|
||||
fowl
|
||||
sex
|
||||
sexy
|
||||
prostitute
|
||||
whore
|
||||
harlot
|
||||
hooker
|
||||
gender
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user