欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Filter高级开发(二)——实现敏感字符过滤功能

程序员文章站 2022-07-15 10:46:08
...

在实际开发中,我们如果真正要做一个上线的网站,就要考虑到过滤敏感字符(敏感词)。 
敏感词可分为三大类:

  • 禁用词,我们用数字1来表示。
  • 审核词,我们用数字2来表示。
  • 替换词,我们用数字3来表示。

为了实现敏感字符过滤功能,首先在网上下载一个敏感词库,然后在Eclipse中新建一个动态Web项目——day19_words。 
这里我们介绍一个新技术:在项目day19_words下新建一个文件夹——config,如下: 
Filter高级开发(二)——实现敏感字符过滤功能 
然后,右键文件夹config→Build Path→Use as Source Folder(源目录),如下所示: 
Filter高级开发(二)——实现敏感字符过滤功能 
此时文件夹config就会在类目录路径下,最终会发布到classes目录下。 
接着在config目录下创建一个cn.itcast.words包,将敏感词库拷贝到此包下,如下: 
Filter高级开发(二)——实现敏感字符过滤功能 
至此,前期的准备工作我们已经做好了。下面我们正式写代码来实现这一功能。 
我们先在cn.itcast.web.filter包下编写一个敏感字符过滤器——WordsFilter.java。 
Filter高级开发(二)——实现敏感字符过滤功能 
现在我们思考这个过滤器该怎么写。当tomcat服务器启动day19_words这个web应用时,程序就要从config目录下的cn.itcast.words包下将敏感词库加载到内存中。也就是说该web应用一启动时,首先要将敏感词库读到系统里面去,而且敏感词库只要读一遍就行了。我们可以在静态代码块里面做,但是我们还有一种方法,可以在init方法里面做,因为filter对象只会创建一次,init方法也只会执行一次。 
此时WordsFilter过滤器可以写为:

public class WordsFilter implements Filter {

    private List<String> banWords = new ArrayList<String>(); // 禁用词
    private List<String> auditWords = new ArrayList<String>(); // 审核词
    private List<String> replaceWords = new ArrayList<String>(); // 替换词

    // WordsFilter过滤器只要一装载,WordsFilter对象只要一创建出来,init方法就会执行,init方法一执行,就会往List集合里面装东西。
    /*
     * 首先要将敏感词库读到系统里面去,而且敏感词库只要读一遍就行了。
     * 我们可以在静态代码块里面做,但是我们还有一种方法,可以在init方法里面做,
     * 因为filter对象只会创建一次,init方法也只会执行一次。
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try {
            String path = WordsFilter.class.getClassLoader().getResource("cn/itcast/words").getPath();
            File[] files = new File(path).listFiles(); 
            for (File file : files) {
                if (!file.getName().endsWith(".txt")) {
                    continue;
                }

                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line=br.readLine()) != null) {
                    String[] s = line.split("\\|");
                    if (s.length != 2) {
                        continue;
                    }
                    if (s[1].trim().equals("1")) {
                        banWords.add(s[0].trim());
                    }
                    if (s[1].trim().equals("2")) {
                        auditWords.add(s[0].trim());
                    }
                    if (s[1].trim().equals("3")) {
                        replaceWords.add(s[0].trim());
                    }
                }
            }
            System.out.println("hahaha"); // 作断点调试用
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

    }

    @Override
    public void destroy() {

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

WordsFilter过滤器只要一装载,WordsFilter对象只要一创建出来,init方法就会执行,init方法一执行,就会往List集合里面装东西。此时我们可以在代码System.out.println("hahaha");处打一个断点进行调试,然后Watch三个List集合,会发现这三个List集合都装载了东西。 
首先我们来检查提交数据中是否包含禁用词。 
此刻我们是不知道客户机要提交过来的数据的,也即不知道客户机会以什么名称提交数据过来, 所以我们应得到客户机提交的所有数据,然后挨个检查,那怎么得到客户机提交的所有数据呢?——可得到客户机提交的所有数据的名称,然后挨个取出来检查即可。 
此时WordsFilter过滤器的代码可以写为:

public class WordsFilter implements Filter {

    private List<String> banWords = new ArrayList<String>(); // 禁用词
    private List<String> auditWords = new ArrayList<String>(); // 审核词
    private List<String> replaceWords = new ArrayList<String>(); // 替换词

    // WordsFilter过滤器只要一装载,WordsFilter对象只要一创建出来,init方法就会执行,init方法一执行,就会往List集合里面装东西。
    /*
     * 首先要将敏感词库读到系统里面去,而且敏感词库只要读一遍就行了。
     * 我们可以在静态代码块里面做,但是我们还有一种方法,可以在init方法里面做,
     * 因为filter对象只会创建一次,init方法也只会执行一次。
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try {
            String path = WordsFilter.class.getClassLoader().getResource("cn/itcast/words").getPath();
            File[] files = new File(path).listFiles(); 
            for (File file : files) {
                if (!file.getName().endsWith(".txt")) {
                    continue;
                }

                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line=br.readLine()) != null) {
                    String[] s = line.split("\\|");
                    if (s.length != 2) {
                        continue;
                    }
                    if (s[1].trim().equals("1")) {
                        banWords.add(s[0].trim());
                    }
                    if (s[1].trim().equals("2")) {
                        auditWords.add(s[0].trim());
                    }
                    if (s[1].trim().equals("3")) {
                        replaceWords.add(s[0].trim());
                    }
                }
            }
            System.out.println("hahaha"); // 作断点调试用
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        // 检查提交数据是否包含禁用词
        /*
         * 此刻是不知道客户机要提交过来的数据的,也即不知道客户机会以什么名称提交数据过来,
         * 所以应得到客户机提交的所有数据,然后挨个检查,怎么得到客户机提交的所有数据呢?
         * 可得到客户机提交的所有数据的名称,然后挨个取出来检查即可。
         */
        Enumeration<String> e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            String data = request.getParameter(name); // 乱码:82342949842934*76%,所以这里还要解决乱码
            // String regexData = data.replaceAll(" +", "");
            for (String regex : banWords) {
                Pattern pattern = Pattern.compile(regex); // 编译regex这个正则表达式,得到代表此正则表达式的对象
                Matcher m = pattern.matcher(data); // 看data数据里面有没有和该正则表达式相匹配的内容
                if (m.find()) { // 匹配器的find方法若返回true,则客户机提交的数据里面有和正则表达式相匹配的内容
                    request.setAttribute("message", "文章中包含非法词汇,请检查后再提交!!!");
                    request.getRequestDispatcher("/message.jsp").forward(request, response);
                    return;
                }
            }
        }

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

编写玩上述WordsFilter过滤器之后,就要在web.xml文件中配置该过滤器了,但是一定得记住在配置该过滤器之前,一定得要配置解决全站中文乱码的过滤器,关于如何编写该过滤器可以参考我的笔记Filter高级开发(一)——使用Decorator模式包装request对象解决get和post请求方式下的中文乱码问题

<filter>
    <filter-name>CharacterEncodingFilter2</filter-name>
    <filter-class>cn.itcast.web.filter.CharacterEncodingFilter2</filter-class>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>WordsFilter</filter-name>
    <filter-class>cn.itcast.web.filter.WordsFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>WordsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

接着在WebRoot根目录下新建一个测试页面——form.jsp,form.jsp页面的内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="/day19_words/ServletDemo1" method="post">
        <textarea rows="5" cols="50" name="resume"></textarea>
        <br /> <input type="submit" value="提交">
    </form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

再在WebRoot根目录下新建一个全局消息显示页面——message.jsp,message.jsp页面的内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    ${message }
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

当有人在form.jsp页面中填写内容并提交时,交给一个Servlet处理,所以应在cn.itcast.web.servlet包下创建一个Servlet——ServletDemo1.java。 
Filter高级开发(二)——实现敏感字符过滤功能 
ServletDemo1类的具体代码如下:

public class ServletDemo1 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String data = request.getParameter("resume");
        response.getWriter().write(data);

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

现在我们来测试提交数据中是否包含禁用词,测试结果为: 
Filter高级开发(二)——实现敏感字符过滤功能 
虽然以上简单的测试通过了,但是人是非常复杂的动物,我们看一下在disu.txt文件中的禁用词。 
Filter高级开发(二)——实现敏感字符过滤功能 
有些人不会按照规矩来输入生儿子没屁眼这样的字符串,他更有可能输入生 儿 子 没 屁 眼这样的字符串,那么WordsFilter过滤器是检查不出来提交的数据中是否包含禁用词的,为了能够检查出来这样的禁用词,我们可以将那些破坏者提交的数据中的空格全部替换为"",然后用替换掉的数据去和生儿子没屁眼这样的正则表达式相匹配,并且我们另外还要保存一份破坏者提交的原始数据。所以WordsFilter过滤器中的doFilter(…)方法要修改为:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        // 检查提交数据是否包含禁用词
        /*
         * 此刻是不知道客户机要提交过来的数据的,也即不知道客户机会以什么名称提交数据过来,
         * 所以应得到客户机提交的所有数据,然后挨个检查,怎么得到客户机提交的所有数据呢?
         * 可得到客户机提交的所有数据的名称,然后挨个取出来检查即可。
         */
        Enumeration<String> e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            String data = request.getParameter(name); // 乱码:82342949842934*76%,所以还要解决乱码
            String regexData = data.replaceAll(" +", "");
            for (String regex : banWords) {
                Pattern pattern = Pattern.compile(regex); // 编译regex这个正则表达式,得到代表此正则表达式的对象
                Matcher m = pattern.matcher(regexData); // 看regexData数据里面有没有和该正则表达式相匹配的内容
                if (m.find()) { // 匹配器的find方法若返回true,则客户机提交的数据里面有和正则表达式相匹配的内容
                    request.setAttribute("message", "文章中包含非法词汇,请检查后再提交!!!");
                    request.getRequestDispatcher("/message.jsp").forward(request, response);
                    return;
                }
            }
        }

        chain.doFilter(request, response);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

由于破坏者是人,他就会想方设法地进行破坏,他不会简单地输入生 儿 子 没 屁 眼这样的字符串,他更加有可能会输入生*儿*子*没$屁#眼等等等这样的字符串,总之,破坏者就一定会搞破坏,我们写代码去防他,实在是防不胜防!!!虽然我们的处境很恶劣,但是我们程序员还是要竭尽全力地去防住破坏者,这是我们的职责,即使防不住!我们可以修改disu.txt文件的内容,在一定程度上去防他们。 
Filter高级开发(二)——实现敏感字符过滤功能 
以上这只是在一定的程度上去防破坏者,并不是防守得水泄不通,如果非得防守得天衣无缝,那就对提交的数据进行审核,管理员审核通过才发表,只要管理员觉得有一点不符合正确政治思想的东西,就不给其发表。 
我们在上面检查完提交数据中是否包含禁用词之后,接下来就要检查提交数据中是否包含审核词。 
现在我们来思考一个问题:文章中包含审核词,一提交,那么系统会怎么处理呢?——过滤器检查,检查文章包含审核词,过滤器应该把审核词高亮,然后再存到数据库里面去,方便管理员去审核,你要是不高亮,一篇文章几千字,管理员从中找一个审核词,眼睛都要找瞎啊! 
当有人在form.jsp页面中填写内容并提交时,要交给一个Servlet——ServletDemo1去处理。ServletDemo1的具体代码为:

public class ServletDemo1 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String data = request.getParameter("resume");
        response.getWriter().write(data);

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

对于代码String data = request.getParameter("resume");而言,获取到的是原始数据,而不是高亮之后的数据,所以可以说request的getParameter方法是不行的,所以我们使用Decorator模式包装request对象,增强其getParameter方法。 
那么此时WordsFilter过滤器的代码应该修改为:

public class WordsFilter implements Filter {

    private List<String> banWords = new ArrayList<String>(); // 禁用词
    private List<String> auditWords = new ArrayList<String>(); // 审核词
    private List<String> replaceWords = new ArrayList<String>(); // 替换词

    // WordsFilter过滤器只要一装载,WordsFilter对象只要一创建出来,init方法就会执行,init方法一执行,就会往List集合里面装东西。
    /*
     * 首先要将敏感词库读到系统里面去,而且敏感词库只要读一遍就行了。
     * 我们可以在静态代码块里面做,但是我们还有一种方法,可以在init方法里面做,
     * 因为filter对象只会创建一次,init方法也只会执行一次。
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try {
            String path = WordsFilter.class.getClassLoader().getResource("cn/itcast/words").getPath();
            File[] files = new File(path).listFiles(); 
            for (File file : files) {
                if (!file.getName().endsWith(".txt")) {
                    continue;
                }

                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line=br.readLine()) != null) {
                    String[] s = line.split("\\|");
                    if (s.length != 2) {
                        continue;
                    }
                    if (s[1].trim().equals("1")) {
                        banWords.add(s[0].trim());
                    }
                    if (s[1].trim().equals("2")) {
                        auditWords.add(s[0].trim());
                    }
                    if (s[1].trim().equals("3")) {
                        replaceWords.add(s[0].trim());
                    }
                }
            }
            System.out.println("hahaha"); // 作断点调试用
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        // 检查提交数据是否包含禁用词
        /*
         * 此刻是不知道客户机要提交过来的数据的,也即不知道客户机会以什么名称提交数据过来,
         * 所以应得到客户机提交的所有数据,然后挨个检查,怎么得到客户机提交的所有数据呢?
         * 可得到客户机提交的所有数据的名称,然后挨个取出来检查即可。
         */
        Enumeration<String> e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            String data = request.getParameter(name); // 乱码:82342949842934*76%,所以还要解决乱码
            // String regexData = data.replaceAll(" +", "");
            for (String regex : banWords) {
                Pattern pattern = Pattern.compile(regex); // 编译regex这个正则表达式,得到代表此正则表达式的对象
                Matcher m = pattern.matcher(data); // 看data数据里面有没有和该正则表达式相匹配的内容
                if (m.find()) { // 匹配器的find方法若返回true,则客户机提交的数据里面有和正则表达式相匹配的内容
                    request.setAttribute("message", "文章中包含非法词汇,请检查后再提交!!!");
                    request.getRequestDispatcher("/message.jsp").forward(request, response);
                    return;
                }
            }
        }

        // 检查审核词
        chain.doFilter(new MyRequset(request), response);
    }

    class MyRequset extends HttpServletRequestWrapper {
        private HttpServletRequest request;
        public MyRequset(HttpServletRequest request) {
            super(request);
            this.request = request;
        }
        @Override
        public String getParameter(String name) {

            String data = this.request.getParameter(name);
            if (data == null) {
                return null;
            }

            for (String regex : auditWords) {
                Pattern p = Pattern.compile(regex);
                Matcher m = p.matcher(data);
                if (m.find()) { // 我有一把仿真手枪,你要电鸡吗??
                    String value = m.group(); // 找出客户机提交的数据中和正则表达式相匹配的数据
                    data = data.replaceAll(regex, "<font color='red'>" + value + "</font>");
                }
            }

            return data;
        }
    }

    @Override
    public void destroy() {

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112

现在我们来测试提交数据中是否包含审核词,测试结果为: 
Filter高级开发(二)——实现敏感字符过滤功能 
我们在上面检查完提交数据中是否包含禁用词和审核词之后,最后就要检查提交数据中是否包含替换词了。 
同检查提交数据中是否包含审核词一样,我们希望request的getParameter方法内部检查已提交的内容里面有没有替换词,如果包含替换词,直接替换返回,所以还要增强这个方法。所以,最终我们的WordsFilter过滤器就全部写好了,其具体代码为:

public class WordsFilter implements Filter {

    private List<String> banWords = new ArrayList<String>(); // 禁用词
    private List<String> auditWords = new ArrayList<String>(); // 审核词
    private List<String> replaceWords = new ArrayList<String>(); // 替换词

    // WordsFilter过滤器只要一装载,WordsFilter对象只要一创建出来,init方法就会执行,init方法一执行,就会往List集合里面装东西。
    /*
     * 首先要将敏感词库读到系统里面去,而且敏感词库只要读一遍就行了。
     * 我们可以在静态代码块里面做,但是我们还有一种方法,可以在init方法里面做,
     * 因为filter对象只会创建一次,init方法也只会执行一次。
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try {
            String path = WordsFilter.class.getClassLoader().getResource("cn/itcast/words").getPath();
            File[] files = new File(path).listFiles(); 
            for (File file : files) {
                if (!file.getName().endsWith(".txt")) {
                    continue;
                }

                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line=br.readLine()) != null) {
                    String[] s = line.split("\\|");
                    if (s.length != 2) {
                        continue;
                    }
                    if (s[1].trim().equals("1")) {
                        banWords.add(s[0].trim());
                    }
                    if (s[1].trim().equals("2")) {
                        auditWords.add(s[0].trim());
                    }
                    if (s[1].trim().equals("3")) {
                        replaceWords.add(s[0].trim());
                    }
                }
            }
            System.out.println("hahaha"); // 作断点调试用
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        // 检查提交数据是否包含禁用词
        /*
         * 此刻是不知道客户机要提交过来的数据的,也即不知道客户机会以什么名称提交数据过来,
         * 所以应得到客户机提交的所有数据,然后挨个检查,怎么得到客户机提交的所有数据呢?
         * 可得到客户机提交的所有数据的名称,然后挨个取出来检查即可。
         */
        Enumeration<String> e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            String data = request.getParameter(name); // 乱码:82342949842934*76%,所以还要解决乱码
            // String regexData = data.replaceAll(" +", "");
            for (String regex : banWords) {
                Pattern pattern = Pattern.compile(regex); // 编译regex这个正则表达式,得到代表此正则表达式的对象
                Matcher m = pattern.matcher(data); // 看data数据里面有没有和该正则表达式相匹配的内容
                if (m.find()) { // 匹配器的find方法若返回true,则客户机提交的数据里面有和正则表达式相匹配的内容
                    request.setAttribute("message", "文章中包含非法词汇,请检查后再提交!!!");
                    request.getRequestDispatcher("/message.jsp").forward(request, response);
                    return;
                }
            }
        }

        // 检查审核词

        // 检查替换词
        chain.doFilter(new MyRequset(request), response);
    }

    class MyRequset extends HttpServletRequestWrapper {
        private HttpServletRequest request;
        public MyRequset(HttpServletRequest request) {
            super(request);
            this.request = request;
        }
        @Override
        public String getParameter(String name) {

            String data = this.request.getParameter(name);
            if (data == null) {
                return null;
            }

            for (String regex : auditWords) {
                Pattern p = Pattern.compile(regex);
                Matcher m = p.matcher(data);
                if (m.find()) { // 我有一把仿真手枪,你要电鸡吗??
                    String value = m.group(); // 找出客户机提交的数据中和正则表达式相匹配的数据
                    data = data.replaceAll(regex, "<font color='red'>" + value + "</font>");
                }
            }

            for (String regex : replaceWords) {
                Pattern p = Pattern.compile(regex);
                Matcher m = p.matcher(data);
                if (m.find()) { // 我有一把仿真手枪,你要电鸡和四大舰队吗??
                    data = data.replaceAll(regex, "*******");
                }
            }

            return data;
        }
    }

    @Override
    public void destroy() {

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

现在我们来测试提交数据中是否包含替换词,测试结果为: 
Filter高级开发(二)——实现敏感字符过滤功能 
至此,实现敏感字符过滤功能的过滤器我们才算写完了。

原文地址:http://blog.csdn.net/yerenyuan_pku/article/details/52488573

相关标签: filter