zoukankan      html  css  js  c++  java
  • JavaWeb 过滤敏感词汇

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

    检查、替换敏感词汇有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);
        }
    }

    效果

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

  • 相关阅读:
    Notepadd ++ PluginManager安装
    Srping cloud Ribbon 自定义负载均衡
    Spring cloud Eureka 和 Zookeeper 比较
    Spring cloud info信息显示
    kafka 在Windows端安装 找不到或无法加载主类 的解决方案
    Linux kafka 单机安装
    mina
    @bzoj
    @51nod
    @topcoder
  • 原文地址:https://www.cnblogs.com/chy18883701161/p/11437689.html
Copyright © 2011-2022 走看看