返回顶部

代理模式使用过滤器实现对敏感词汇的过滤

一.代理模式 概念:

​ 代理模式 是作为二十三种设计模式之一,所谓的设计模式就是一些通用的解决固定问题的一些方式

  • 真实对象 : 被代理的对象
  • 代理对象
  • 代理模式: 代理对象代理真实对象 , 达到增强真实对象功能的目的
二.实现方式

在内存中形成代理类

三.分析

​ 1.代理对象和真实对象实现相同的接口

​ 2.代理对象 = Proxy.newProxyInstance();

​ 3.使用代理对象调用方法

​ 4.增强方法

​ 增强方式:

​ 1)增强参数列表

​ 2)增强返回值类型

​ 3)增强方法体执行逻辑

四.实现

对于使用代理模式对过滤器的编写 需要了解的是:

Proxy.newProxyInstance()方法接受三个参数:

  • ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
  • Class[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
  • InvocationHandler:指定``动态处理器,执行目标对象的方法时,会触发事件处理器的方法

SensitiveWordsFilter文件内容:

/**
 * 需求: 敏感词汇的过滤 ,在txt文件中读取敏感词汇, 对于出现的敏感词汇能够替换为***
 * 分析: 对request对象进行增强 增强获取参数相关方法
 *       放行, 传递代理对象
 */                        //拦截路径设置为"/*"代表全局
@WebFilter(filterName = "SensitiveWordsFilter", urlPatterns = "/*")
public class SensitiveWordsFilter implements Filter {
    //创建存放敏感词汇的list集合
    private List<String> list = new ArrayList<>();
    public void init(FilterConfig config) throws ServletException {
        try {
            //1.读取文件的真实路径
            ServletContext servletContext = config.getServletContext();
            // src下文件的真实路径获取 : /WEB-INF/classes/文件.文件后缀名
            String realPath = servletContext.getRealPath("/WEB-INF/classes/sensitiveWords.txt");
            System.out.println(realPath);
            //2.创建缓冲流对象
            BufferedReader br = new BufferedReader(new FileReader(realPath));
            //3.读取流对象
            String line =null;
            while ((line=br.readLine())!=null){
                //4.将读取到的每一行数据加入到list集合中
                list.add(line);
            }
            System.out.println(list);
            //释放资源
            br.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //1.创建代理对象
        ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //2.增强 getParameter方法
                if (method.getName().equals("getParameter")){
                    //2.1获取返回值 增强 返回值
                    String value= (String) method.invoke(req,args);
                    //如果返回值不为空
                    if (value!=null){
                        //2.2 对敏感词汇进行遍历
                        for (String str : list) {
                            //3.如果request.getParameter()获得的值中包含  敏感词汇 则进行替换
                            if (value.contains(str)){
                                value = value.replaceAll(str,"***");
                            }

                        }
                    }
                    //返回 value
                    return value;
                }
  //invoke方法就是调用被代理接口的所有方法时需要调用的,返回的值是被代理接口的一个实现类。
                return method.invoke(req,args);
            }
        });
        //放行
        chain.doFilter(proxy_req,resp);
    }

    public void destroy() {
    }


}

在项目的src路径下, 有一个名为 sensitiveWords.txt文件 ,文件里存放的是敏感词汇 , 项目下新建的有一个TestServlet的测试Servlet

TestServlet内的文件内容:

/*用于测试的servlet*/
@WebServlet(name = "TestServlet", urlPatterns = "/testServlet")
public class TestServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        String msg = request.getParameter("msg");
        System.out.println(name+"--"+msg);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
五.测试

在sensitiveWords.txt文件中存放两个敏感词汇:坏蛋,笨蛋, 注意两个词汇各占一行, 启动服务器 ,

在浏览器中输入 http://localhost/testServlet?name=大坏蛋&msg=大笨蛋

查看控制台输出 :

大***--大***

至此,说明敏感词汇过滤成功

六.总结

实现对于敏感词汇的过滤实现方式有很多种 , 本人的方法其实主要就是使用代理对象对request的方法进行增强 ,

注意: 代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理 动态代理是在程序运行时通过反射机制动态创建的。

posted @ 2020-07-13 10:17  洛水良遥  阅读(210)  评论(0编辑  收藏  举报