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

JavaWeb 过滤敏感词汇

程序员文章站 2022-03-20 21:09:33
提交的表单数据,常常要检查有没有敏感词汇,如果有,需要给出提示,或者替换为*。 检查、替换敏感词汇有3种常用的方式 (1)在Servlet中操作。 (2)在Filter中先检查。如果要替换敏感词汇,request没有setParameter()方法重新设置请求参数,怎么向Servlet中传递替换后的 ......

 

提交的表单数据,常常要检查有没有敏感词汇,如果有,需要给出提示,或者替换为*。

 

 

检查、替换敏感词汇有3种常用的方式

(1)在servlet中操作。

(2)在filter中先检查。如果要替换敏感词汇,request没有setparameter()方法重新设置请求参数,怎么向servlet中传递替换后的请求参数?使用request.setattribute()把这些修改后的请求参数放到request域中即可。

(3)在filter中创建request的代理,增强getparameter()方法,然后传入代理: chain.dofilter(request的代理对象 resp); 。如何增强getparameter()方法?getparameter()不是要返回一个string吗,先调用原来的getparameter()获取值,检查值中是否有敏感词汇,有就替换掉敏感词汇,返回替换后的值,没有敏感词汇就返回原值。

 

(1)、(2)较简单,但很繁琐,(3)最常用。此处只演示(3)。

 

 

 

敏感词汇

敏感词汇很多,可以存储在数据库中,也可以存储在文本文件中。

此处我们在项目根目录下新建文件夹resource,标识为资源根目录。resource下新建 illegal_word.txt 存储敏感词汇,一行一个。

煞笔
制杖
cxk

每次都从数据库读或文件取读敏感词汇,会增加时间开销,可以把取敏感词汇放到servletcontext中,全局共享、随时可用。

怎么放?filter的init()方法在filter生命周期中只调用一次,可以在init()中读取敏感词汇,将敏感词汇放到arraylist<string>中,再将这个list放到servletcontext中,这样避免了每访问一次就读取一次的问题。

 

 

 

表单

<form action="handlerservlet" method="post">
        评论:<textarea name="comment" rows="10" cols="50"></textarea>
        <button type="submit">提交</button>
    </form>

 

 

 

filter

@webfilter("/handlerservlet")
public class handlerfilter implements filter {
    public void destroy() {
    }

    public void dofilter(servletrequest req, servletresponse resp, filterchain chain) throws servletexception, ioexception {
        //解决中文乱码
        req.setcharacterencoding("utf-8");
        resp.setcontenttype("text/html;charset=utf-8");

      //jdk动态代理  
        classloader classloader = req.getclass().getclassloader();
        class<?>[] interfaces = req.getclass().getinterfaces();
        //创建invocationhandler接口的实例。此处使用匿名内部类来创建
        invocationhandler invocationhandler = new invocationhandler() {
            @override
            public object invoke(object proxy, method method, object[] args) throws throwable {
                //只增强getparameter()
                if(method.getname().equals("getparameter")){
                    //调用原有的getparameter()获取参数值
                    string text = (string) method.invoke(req, args);

                    //检查是否有敏感词汇
                    object obj = req.getservletcontext().getattribute("illegal_word_list");
                    arraylist<string> list=(arraylist<string>)obj;
                    for (string word : list){
                        if (text.contains(word)){
                            //用一个*替换一个字符
                            string replac="";
                            for(int i=0;i<word.length();i++){
                                replac+="*";
                            }
                            //替换所有匹配
                            text = text.replaceall(word, replac);
                        }
                    }

                    return text;
                }

                //如果调用的是getparameter(),执行到前面的return就结束了,不会执行到此
                //如果调用的不是getparameter(),就调用原方法,不做修改
                object returnvalue=method.invoke(req,args);  //调用目标方法
                return returnvalue;
            }
        };

        //创建req的代理对象
        object proxyinstance = proxy.newproxyinstance(classloader, interfaces, invocationhandler);
        //强转为servletrequest
        servletrequest reqproxyinstance = (servletrequest) proxyinstance;

        //传入req的代理对象
        chain.dofilter(reqproxyinstance, resp);
    }

    public void init(filterconfig config) throws servletexception {
        inputstream is= this.getclass().getresourceasstream("/illegal_word.txt");
        //因为要readline()一行一行地读,需要使用bufferedreader流,所以先转换为reader,再加buffer
        inputstreamreader isr = new inputstreamreader(is);
        bufferedreader br = new bufferedreader(isr);
        arraylist<string> list=new arraylist<>();
        string str=null;
        while (true){
            try {
                str=br.readline();
                if (str!=null)
                    list.add(str);
                else
                    break;
            } catch (ioexception e) {
                e.printstacktrace();
            }
        }

        //放到servletcontext中
        config.getservletcontext().setattribute("illegal_word_list",list);
    }


}    

 

 

 

 

 

测试用的servlet

@webservlet("/handlerservlet")
public class handlerservlet extends httpservlet {
    protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
        string comment = request.getparameter("comment");
        response.getwriter().write(comment);
    }

    protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
        dopost(request,response);
    }
}

 

 

 

 

效果

JavaWeb   过滤敏感词汇

 

 

 

JavaWeb   过滤敏感词汇

 

 

这种方式是增强getparameter(),通过getparameter()获取参数值时,都会先自动检测是否有敏感词汇。