需求:
- 搜索栏展示当前登陆的个人用户的搜索历史记录,删除个人历史记录
- 用户在搜索栏输入某字符,则将该字符记录下来 ,记录该字符被搜索的个数以及当前的时间戳
- 每当用户查询了已在redis存在了的字符时,则直接累加个数, 用来获取平台上最热查询的十条数据。
- 不雅文字过滤功能。
最后贴上核心的 服务层的代码 :
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Transactional
@Service("redisService")
public class RedisServiceImpl implements RedisService {
//导入数据源
@Resource(name = "redisSearchTemplate")
private StringRedisTemplate redisSearchTemplate;
/**
* 新增一条userid用户在搜索栏的历史记录
* @param searchkey输入的关键词
* @param userid
*/
@Override
public int insertSearchHistoryByUserId(String userid, String searchkey) {
String shistory = RedisKeyUtils.getSearchHistoryKey(userid);
boolean b = redisSearchTemplate.hasKey(shistory);
if (b) {
Object hk = redisSearchTemplate.opsForHash().get(shistory, searchkey);
if (hk != null) {
return 1;
}else{
redisSearchTemplate.opsForHash().put(shistory, searchkey, "1");
}
}else{
redisSearchTemplate.opsForHash().put(shistory, searchkey, "1");
}
return 1;
}
/**
* 删除个人历史数据
* @param searchkey输入的关键词
* @param userid
*/
@Override
public Long delSearchHistoryByUserId(String userid, String searchkey) {
String shistory = RedisKeyUtils.getSearchHistoryKey(userid);
return redisSearchTemplate.opsForHash().delete(shistory, searchkey);
}
/**
* 获取个人历史数据列表
* @param userid
*/
@Override
public List getSearchHistoryByUserId(String userid) {
List stringList = null;
String shistory = RedisKeyUtils.getSearchHistoryKey(userid);
boolean b = redisSearchTemplate.hasKey(shistory);
if(b){
Cursor> cursor = redisSearchTemplate.opsForHash().scan(shistory, ScanOptions.NONE);
while (cursor.hasNext()) {
Map.Entry
不雅文字功能实现,代码如下:
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
//屏蔽敏感词初始化
@Configuration
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SensitiveWordInit {
// 字符编码
private String ENCODING = "UTF-8";
// 初始化敏感字库
public Map initKeyWord() throws IOException {
// 读取敏感词库 ,存入Set中
Set wordSet = readSensitiveWordFile();
// 将敏感词库加入到HashMap中
return addSensitiveWordToHashMap(wordSet);
}
// 读取敏感词库 ,存入HashMap中
private Set readSensitiveWordFile() throws IOException {
Set wordSet = null;
ClassPathResource classPathResource = new ClassPathResource("static/censorword.txt");
InputStream inputStream = classPathResource.getInputStream();
try {
InputStreamReader read = new InputStreamReader(inputStream, ENCODING);
wordSet = new HashSet();
BufferedReader br = new BufferedReader(read);
String txt = null;
while ((txt = br.readLine()) != null) {
wordSet.add(txt);
}
br.close();
read.close();
} catch (Exception e) {
e.printStackTrace();
}
return wordSet;
}private Map addToHashMap(Set wordSet) {
// 初始化敏感词容器
Map wordMap = new HashMap(wordSet.size());
for (String word : wordSet) {
Map nowMap = wordMap;
for (int i = 0;
i < word.length();
i++) {
char keyChar = word.charAt(i);
Object tempMap = nowMap.get(keyChar);
if (tempMap != null) {
nowMap = (Map) tempMap;
}
// 不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个
else {
// 设置标志位
Map newMap = new HashMap();
newMap.put("isEnd", "0");
nowMap.put(keyChar, newMap);
nowMap = newMap;
}
// 最后一个
if (i == word.length() - 1) {
nowMap.put("isEnd", "1");
}
}
}
return wordMap;
}
}
工具类代码 :
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
//敏感词过滤器:DFA算法进行敏感词过滤
public class SensitiveFilter {
//敏感词过滤器:利用DFA算法进行敏感词过滤
private Map sensitiveWordMap = null;
// 最小匹配规则
public static int minMatchType = 1;
// 最大匹配规则
public static int maxMatchType = 2;
private static SensitiveFilter instance = null;
// 构造函数,初始化敏感词库
private SensitiveFilter() throws IOException {
sensitiveWordMap = new SensitiveWordInit().initKeyWord();
}
// 获取单例
public static SensitiveFilter getInstance() throws IOException {
if (null == instance) {
instance = new SensitiveFilter();
}
return instance;
}
// 获取文字中的敏感词
public Set getSensitiveWord(String txt, int matchType) {
Set sensitiveWordList = new HashSet();
for (int i = 0;
i < txt.length();
i++) {
// 判断是否包含敏感字符
int length = CheckSensitiveWord(txt, i, matchType);
// 存在,加入list中
if (length > 0) {
sensitiveWordList.add(txt.substring(i, i + length));
i = i + length - 1;
}
}
return sensitiveWordList;
}
// 替换敏感字字符
public String replaceSensitiveWord(String txt, int matchType,
String replaceChar) {
String resultTxt = txt;
// 获取所有的敏感词
Set set = getSensitiveWord(txt, matchType);
Iterator iterator = set.iterator();
String word = null;
String replaceString = null;
while (iterator.hasNext()) {
word = iterator.next();
replaceString = getReplaceChars(replaceChar, word.length());
resultTxt = resultTxt.replaceAll(word, replaceString);
}
return resultTxt;
}
/**
* 获取替换字符串
*
* @param replaceChar
* @param length
* @return
*/
private String getReplaceChars(String replaceChar, int length) {
String resultReplace = replaceChar;
for (int i = 1;
i < length;
i++) {
resultReplace += replaceChar;
}
return resultReplace;
}
/**
* 检查文字中是否包含敏感字符,检查规则如下:
* 如果存在,则返回敏感词字符的长度,不存在返回0
* @param txt
* @param beginIndex
* @param matchType
* @return
*/
public int CheckSensitiveWord(String txt, int beginIndex, int matchType) {
// 敏感词结束标识位:用于敏感词只有1位的情况
boolean flag = false;
// 匹配标识数默认为0
int matchFlag = 0;
Map nowMap = sensitiveWordMap;
for (int i = beginIndex;
i < txt.length();
i++) {
char word = txt.charAt(i);
// 获取指定key
nowMap = (Map) nowMap.get(word);
// 存在,则判断是否为最后一个
if (nowMap != null) {
// 找到相应key,匹配标识+1
matchFlag++;
// 如果为最后一个匹配规则,结束循环,返回匹配标识数
if ("1".equals(nowMap.get("isEnd"))) {
// 结束标志位为true
flag = true;
// 最小规则,直接返回,最大规则还需继续查找
if (SensitiveFilter.minMatchType == matchType) {
break;
}
}
}
// 不存在,直接返回
else {
break;
}
}
if (SensitiveFilter.maxMatchType == matchType){
if(matchFlag < 2 || !flag){//长度必须大于等于1,为词
matchFlag = 0;
}
}
if (SensitiveFilter.minMatchType == matchType){
if(matchFlag < 2 && !flag){//长度必须大于等于1,为词
matchFlag = 0;
}
}
return matchFlag;
}
}
controller层直接调用方法判断:
//非法敏感词汇判断
SensitiveFilter filter = SensitiveFilter.getInstance();
int n = filter.CheckSensitiveWord(searchkey,0,1);
if(n > 0){ //存在非法字符
logger.info("这个人输入了非法字符--> {},不知道他到底要查什么~ userid--> {}",searchkey,userid);
return null;
}
敏感文字替换*等字符 :
SensitiveFilter filter = SensitiveFilter.getInstance();
String text = "敏感文字";
String x = filter.replaceSensitiveWord(text, 1, "*");
SensitiveWordInit.java
里面用到的 censorword.text
文件,放到项目里面的 resources 目录下的 static 目录中,这个文件就是不雅文字大全,项目启动的时候会加载该文件。推荐阅读
- 难以想象SpringBoot中的条件注解底层居然是这样实现的
- SpringBoot 一个依赖搞定 session 共享,没有比这更简单的方案了!
- JAVA|Springboot+Vue
- SpringBoot|SpringBoot 搭建 Web 前后端分离项目
- security|spring security入门--从数据库读取数据实现用户登录访问简单示例四
- Spring|Spring Boot——整合 Thymeleaf模板引擎
- SpringBoot|SpringBoot——SSMP整合案例
- 框架整理|SpringBoot随计——数据访问
- 微服务的学习|微服务08_RabbitMQ的SpringAMQP基本介绍