KeyTree类 这个类的功能是 :
读取硬盘上的key.txt(里面存放的是敏感关键词),将之读入Set中,再讲Set中的元素传入到Map中(通过Map来生成敏感词的树状结构),并传出这个Map(敏感词树)
public Map createKeyWord():创建一个Map类型的词库(敏感词树)
private void readSetToMap(Set<String> keyWordSet): (内部方法)读取敏感词库,将敏感词放入HashSet中
private Set<String> readKeyTxt():(内部方法)读取敏感词库中的内容,将内容添加到set集合中
1 package pingbi; 2 3 /** 4 * keyWordSet:敏感词集合(中间量) 将原始key.txt中的内容先读入到这个变量(keyWordSet)中, 5 * 再由此变量生成敏感词树(keyTreeMap) 6 * newMap、nowMap:一起用来生成敏感词树(keyTreeMap)的 7 * keyTreeMap:敏感词树 8 */ 9 import java.io.BufferedReader; 10 import java.io.File; 11 import java.io.FileInputStream; 12 import java.io.InputStreamReader; 13 import java.util.*; 14 15 /** ----------------初始化敏感词库,将敏感词加入到HashMap中,构建DFA算法模型-----------------*/ 16 public class KeyTree { 17 // private String ENCODING = "GBK"; //字符编码 18 private String ENCODING = "UTF-8"; // 字符编码 19 @SuppressWarnings("rawtypes") 20 private HashMap keyTreeMap;// 敏感词集合 21 22 public HashMap getKeyTreeMap() { 23 return keyTreeMap; 24 } 25 26 @SuppressWarnings("rawtypes") 27 public Map createKeyWord() { 28 try { 29 // 读取敏感词库 30 Set<String> keyWordSet = readKeyTxt(); 31 // 将敏感词库加入到HashMap中 32 readSetToMap(keyWordSet); 33 // spring获取application,然后application.setAttribute("sensitiveWordMap",sensitiveWordMap); 34 } catch (Exception e) { 35 e.printStackTrace(); 36 } 37 return keyTreeMap; 38 } 39 40 /*-------------- 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型--------------*/ 41 @SuppressWarnings({ "rawtypes", "unchecked" }) 42 private void readSetToMap(Set<String> keyWordSet) { 43 keyTreeMap = new HashMap(keyWordSet.size());// 初始化敏感词容器,减少扩容操作 44 String key = null; 45 Map nowMap = null; 46 Map<String, String> newMap = null; 47 // 迭代keyWordSet 48 Iterator<String> iterator = keyWordSet.iterator(); 49 while (iterator.hasNext()) { 50 key = iterator.next(); // 关键字 51 nowMap = keyTreeMap; 52 for (int i = 0; i < key.length(); i++) { 53 char keyChar = key.charAt(i); // 转换成char型 54 Object wordMap = nowMap.get(keyChar); // 获取 55 56 if (wordMap != null) { // 如果存在该key,直接赋值 57 nowMap = (Map) wordMap; 58 } else { // 不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个 59 newMap = new HashMap<String, String>(); 60 newMap.put("isEnd", "0"); // 不是最后一个 61 nowMap.put(keyChar, newMap); 62 nowMap = newMap; 63 } 64 65 if (i == key.length() - 1) { 66 nowMap.put("isEnd", "1"); // 最后一个 67 } 68 } 69 } 70 } 71 72 /*------------------- 读取敏感词库中的内容,将内容添加到set集合中--------------------*/ 73 @SuppressWarnings("resource") 74 private Set<String> readKeyTxt() throws Exception { 75 Set<String> set = null; 76 77 String filepath = "E:\\pingbi\\key.txt"; 78 File file = new File(filepath); // 读取文件 79 // String filename = "key.txt"; 80 81 InputStreamReader read = new InputStreamReader(new FileInputStream(filepath), ENCODING); 82 try { 83 if (file.isFile() && file.exists()) {// 文件流是否存在 84 set = new HashSet<String>(); 85 BufferedReader bufferedReader = new BufferedReader(read); 86 String txt; 87 while ((txt = bufferedReader.readLine()) != null) {// 读取文件,将文件内容放入到set中 88 set.add(txt); 89 } 90 } else {// 不存在抛出异常信息 91 throw new Exception("敏感词库文件不存在"); 92 } 93 } catch (Exception e) { 94 throw e; 95 } finally { 96 read.close();// 关闭文件流 97 } 98 return set; 99 } 100 }
shieldUtil类提供 工具方法
public shieldUtil(): 构造方法,初始化敏感词库
public Set<String> getSensitiveWord(String txt): 获取文字中所有的的敏感词,并放入一个Set中
public String replaceSensitiveWord(String txt, String replaceChar): 替换敏感字字符,替换字符,默认
public int CheckSensitiveWord(String txt, int beginIndex) :检查文字中是否包含敏感字符,检查规则如下: 如果存在,则返回敏感词字符的长度,不存在返回0
public boolean isSensitive(String txt): 判断是否含有敏感词
private String getReplaceChars(String replaceChar, int length): (内部方法)获取替换字符串
1 package pingbi; 2 3 import java.io.*; 4 import java.util.HashSet; 5 import java.util.Iterator; 6 import java.util.Map; 7 import java.util.Set; 8 9 /** 敏感词过滤 */ 10 public class shieldUtil { 11 @SuppressWarnings("rawtypes") 12 private Map keyWord= null;// 树 13 14 /* -------------------构造函数,初始化敏感词库-------------------------- */ 15 public shieldUtil() { 16 keyWord= new KeyTree().createKeyWord(); 17 } 18 19 /*--------------- 获取文字中所有的的敏感词,并放入一个Set中--------------------*/ 20 public Set<String> getSensitiveWord(String txt) { 21 Set<String> sensitiveWordSet = new HashSet<String>(); 22 23 for (int i = 0; i < txt.length(); i++) { 24 int length = CheckSensitiveWord(txt, i);// 判断是否包含敏感字符 25 if (length > 0) {// 存在,加入list中 26 sensitiveWordSet.add(txt.substring(i, i + length)); 27 i = i + length - 1;// 减1的原因,是因为for会自增 28 } 29 } 30 return sensitiveWordSet; 31 } 32 33 /*------------------替换敏感字字符,替换字符,默认------------------*/ 34 public String replaceSensitiveWord(String txt, String replaceChar) { 35 String resultTxt = txt; 36 Set<String> set = getSensitiveWord(txt); // 获取所有的敏感词 37 Iterator<String> iterator = set.iterator(); 38 String word = null; 39 String replaceString = null; 40 while (iterator.hasNext()) { 41 word = iterator.next(); 42 replaceString = getReplaceChars(replaceChar, word.length()); 43 resultTxt = resultTxt.replaceAll(word, replaceString); 44 } 45 return resultTxt; 46 } 47 48 /*-----------------获取替换字符串 -----------------*/ 49 /* 例如,已知匹配到的敏感词长度是3,想要替换成“*”号,则得到的替换字符串为“***” */ 50 private String getReplaceChars(String replaceChar, int length) { 51 String resultReplace = replaceChar; 52 for (int i = 1; i < length; i++) { 53 resultReplace += replaceChar; 54 } 55 return resultReplace; 56 } 57 58 /*--------检查文字中是否包含敏感字符,检查规则如下: 如果存在,则返回敏感词字符的长度,不存在返回0---------*/ 59 // 只匹配一次,成功即返回 60 @SuppressWarnings({ "rawtypes" }) 61 public int CheckSensitiveWord(String txt, int beginIndex) { 62 boolean flag = false;// 敏感词结束标识位:用于敏感词只有1位的情况 63 int matchLength = 0;// 匹配标识数默认为0 64 char word = 0; 65 Map nowMap = keyWord; 66 for (int i = beginIndex; i < txt.length(); i++) { 67 word = txt.charAt(i); 68 nowMap = (Map) nowMap.get(word);// 获取指定key 69 if (nowMap != null) {// 存在,则判断是否为最后一个 70 matchLength++;// 找到相应key,匹配标识+1 71 if ("1".equals(nowMap.get("isEnd"))) {// 如果为最后一个匹配规则,结束循环,返回匹配标识数 72 flag = true;// 结束标志位为true 73 } 74 } else {// 不存在,直接返回 75 break; 76 } 77 } 78 if (matchLength < 2 || !flag) {// 长度必须大于等于1,为词 79 matchLength = 0; 80 } 81 return matchLength; 82 } 83 84 /*----------------------判断是否含有敏感词------------------*/ 85 public boolean isSensitive(String txt) { 86 int matchLength = CheckSensitiveWord(txt, 0); 87 return matchLength > 0; 88 } 89 }
时间: 2024-11-06 19:47:14