五 SpringMvc - 支付宝沙箱和关键字过滤,md5加密,SSM项目重要知识点( 三 )

2.2.2 关键字过滤类/** * Created On : 2022/7/26. * <p> * Author : zhukang * <p> * Description: 敏感字过滤工具类 */@Componentpublic class SensitiveWordFilterUtil {    // 最小匹配规则    public static final int MIN_MATCH_TYPE = 1;    // 最大匹配规则    public static final int MAX_MATCH_TYPE = 2;    // 敏感词集合    public static Map sensitiveWordMap;    // 应用启动后,创建实例对象,自动执行此方法    @PostConstruct    public void init() {        // 从数据库查询敏感词,转换为set集合 将敏感词库加入到HashMap中,确定有穷自动机DFA        sensitiveWordMap = new com.kgc.weddingshop.utils.SensitiveWordInit().initSensitiveWord();        System.out.println("------ " + sensitiveWordMap + "------");    }    /**     * @param : [java.lang.String]     * @return : boolean true 包含;false 不包含     * @author : zhukang     * @date : 2022/7/26     * @description : 是否包含敏感词(默认按最小匹配规则来,只要有敏感词就ok),最小匹配规则     */    public boolean isContainSensitiveWordMin(String txt) {        return isContainSensitiveWord(txt, MIN_MATCH_TYPE);    }    /**     * @param : [java.lang.String, int]     * @return : boolean     * @author : zhukang     * @date : 2022/7/26     * @description : 是否包含敏感词(默认按指定匹配规则来,只要有敏感词就ok)     * 如果敏感词库为:     * * 傻叉     * * 傻叉人     * * 大傻叉     * * 初始化之后为:{傻={叉={人={isEnd=1}, isEnd=1}, isEnd=0}, 大={傻={叉={isEnd=1}, isEnd=0}, isEnd=0}}     * * 1、按最小规则匹配,  匹配 傻叉 的时候,匹配到叉,就为最后一个了 直接break 。如果输入的敏感词是傻叉人,命中的只是傻叉,而不是傻叉人     * * 2、按最大规则匹配,  匹配 傻叉 的时候,匹配到叉,已经为最后一个,但是按照最大规则,会继续匹配人,命中的是傻叉人     * * 3、如果关键词是傻叉猫,两种匹配规则都会匹配到傻叉,会命中,如果输入的是傻叉人猫,按最小规则匹配是傻叉,按最大规则匹配傻叉人,只是匹配敏感词不同     */    public boolean isContainSensitiveWord(String txt, int matchType) {        if (txt == null || "".equals(txt)) {            return false;        }        for (int i = 0; i < txt.length(); i++) {            int matchFlag = this.checkSensitiveWords(txt, i, matchType);            if (matchFlag > 0) {                return true;            }        }        return false;    }    /**     * @param : 待判断文本 起始位置 匹配类型: 1 最小匹配原则;2 最大匹配原则     * @return : int 大于0表示包含敏感词且表示敏感词匹配长度,否则不包含     * @author : zhukang     * @date : 2022/7/26     * @description : 校验是否包含敏感词     */    private static int checkSensitiveWords(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) {                break;            }            // 根据排列组合的匹配,如果出现在敏感词库中,即找到相应key,匹配标识+1            matchFlag++;            // 如果已经匹配到词库中完整的敏感词, 改匹配结束标识,并根据匹配规则判断,是否继续            if ("1".equals(nowMap.get("isEnd"))) {                // 结束标志位为true,已经命中到了一个完整敏感词                flag = true;                // 最小规则,直接返回, 最大规则还需继续查找                if (matchType == MIN_MATCH_TYPE) {                    break;                }            }        }        // 长度必须大于等于1,为词,敏感词只有1个字的情况        if (matchFlag < 2 || !flag) {            matchFlag = 0;        }        return matchFlag;    }    /**     * @param : txt 待判断文本     * @return : 匹配类型: 1 最小匹配原则;2 最大匹配原则     * @author : zhukang     * @date : 2022/7/26     * @description :  获取匹配的敏感词     */    public Set<String> getSensitiveWords(String txt, Integer matchType) {        Set<String> sensitiveWords = new HashSet<>();        for (int i = 0; i < txt.length(); i++) {            Integer length = checkSensitiveWords(txt, i, matchType);            if (length > 0) {                sensitiveWords.add(txt.substring(i, i + length));                // 循环i会+1,所以需-1                i = i + length - 1;            }        }        return sensitiveWords;    }    /**     * @param : txt,文本 matchType 匹配类型: 1 最小匹配原则;2 最大匹配原则     * @return : 替换字符     * @author : zhukang     * @date : 2022/7/26     * @description :  替换敏感词     */    public String replaceSensitiveWords(String txt, Integer matchType, String replaceStr) {        if (txt == null || "".equals(txt)) {            return txt;        }        // 获取所有敏感词        Set<String> sensitiveWords = getSensitiveWords(txt, matchType);        Iterator<String> iterator = sensitiveWords.iterator();        String replaceString = "";        while (iterator.hasNext()) {            String sWord = iterator.next();            replaceString = getReplaceString(replaceStr, sWord.length());            txt = txt.replaceAll(sWord, replaceString);        }        return txt;    }    /**     * @param : replaceStr 替换字符     * @return : 敏感字长度     * @author : zhukang     * @date : 2022/7/26     * @description :  替换为指定字符,没有指定替换字符,默认*     */    private static String getReplaceString(String replaceStr, Integer length) {        // 指定替换字符为*        if (replaceStr == null) {            replaceStr = "*";        }        // 可变字符串对象        StringBuffer replaceString = new StringBuffer();        // 循环遍历,替换内容        for (int i = 0; i < length; i++) {            replaceString.append(replaceStr);        }        return replaceString.toString();    }}

经验总结扩展阅读