Filter和Listener 登录拦截和敏感词汇拦截器JDk动态代理增强GetParameter方法

FilterAndListener


  1. web中的过滤器, 当访问服务器的资源的时候,可以将请求和响应拦截下来
  2. 通用化的处理, 比如说登录的功能,统一的编码问题可以放在过滤器中进行拦截

    快速入门 ##

  3. 定义一个类,实现Filter接口

  4. 复写方法
  5. 配置拦截路径
    1. 注解的配置

     `@WebFilter("/*")
    public class FilterDemo1  implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {

        }

        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("servletDFilterDemo执行了");
            // 放行
           filterChain.doFilter(servletRequest,servletResponse);
        }

        @Override
        public void destroy() {

        }
    }`

2. web.xml 方式的配置
     `
demo1
com.liangxin.web.Filter.FilterDemo1


    demo1

/*
`

3. 过滤器的执行流程
     `WebFilter("/*")
public class FilterDemo2 implements Filter {
public void destroy() {
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    System.out.println("我是用来执行request请求的 ,我是在放行方法doFilter方法之前执行的");
    // 放行
    chain.doFilter(req, resp);
    System.out.println("在放行之后 ,执行请求资源文件或者路径之后, 再回来执行执行放行之后的方法");
}

public void init(FilterConfig config) throws ServletException {

}

`


4. 过滤器的生命周期
    `@WebFilter( "/*")
public class FilterDemo3 implements Filter {
public void destroy() {
    System.out.println("我是destroy方法,在服务器关闭的时候我就会被执行, 只会执行一次,常用来释放资源");
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    System.out.println("我是doFilter方法, 每次拦截的时候我都会执行一次, 相当于servlet中的service方法, 每次访问我就会执行一次");
    chain.doFilter(req, resp);
}

public void init(FilterConfig config) throws ServletException {
    System.out.println("我是init方法,我在服务器启动的时候 就会被执行, 只会执行一次,用来加载资源");

}`

5. 过滤器的配置
    1. 拦截路径的配置
        1. 具体的资源路径---"/index.jsp"---@WebFilter("/index.jsp")
        2. 目录拦截:/user/*--- 在访问/user路径下的所有资源的时候,过滤器就会执行---@WebFilter("/user/findAllServlet")
        3. 后缀名拦截:*.jsp --- 再访问后缀名为*.jsp的资源的时候,过滤器就会执行--- @WebFilter("*.jsp")
        4. 拦截所有--- "/*"---@WebFilter("/*")
    2. 拦截方式的配置:资源被访问的方式
        1. 注解配置 设置dispatcherTypes属性
         @WebFilter(value = "/index.jsp" ,dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.ASYNC,DispatcherType.ERROR,DispatcherType.FORWARD, DispatcherType.INCLUDE})

            1. REQUEST(默认的方式, 浏览器请求)
            2. FORWARD  转发
            3. INCLUDE 包含   
            4. ERROR 错误
            5. ASYNC 异步
        2. web.xml
            1. 设置 上面的五个取值

6. 过滤器的配置链
    1. 多个过滤器的执行顺序
        1. FilterDemo5执行了
            FilterDemo6执行了
            index.jsp执行了
            FilterDemo6回来了执行了
            FilterDemo5回来了执行了

    2.过滤器的执行先后问题
        1. 注解的方式:是根据过滤器的类名字符串的比较,小的先执行(FilterDemo1 < FilterDemo2) demo1先执行
        2.web.xml的方式:配置在上面的先执行

登录验证案例


 `WebFilter( "/*")
public class LoginFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //   获取URI 类型强制转换
        HttpServletRequest request = (HttpServletRequest) req;
        String requestURI = request.getRequestURI();
        //判断 是够路径中包含本身就是登录的内容和cssjs数据 有则放行
        if (requestURI.contains("/login.jsp") || requestURI.contains("/loginServlet")
                || requestURI.contains("/css") || requestURI.contains("/fonts") || requestURI.contains("/js") || requestURI.contains("/checkCodeServlet")) {
            chain.doFilter(request, resp);
        } else {
//            判断session中是否有user有的话就放行 没有则转到登录页面
            HttpSession session = request.getSession();
            Object user = session.getAttribute("user");
            if (user != null) {
                //放行
                chain.doFilter(request, resp);
            } else {
                request.setAttribute("login_msg", "尚未登录,请您登录");
                request.getRequestDispatcher("/login.jsp").forward(request, resp);
            }
        }

        // chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}`

过滤敏感词汇的问题

  1. 动态代理增强方法:
    1. 参数列表
    2. 方法体
    3. 返回值类型
    4. 4.

    `        /**
     *@描述
     *@参数  代理对象动态代理代理对象和真实的对象必须要实现同一个接口
     * Proxy.newProxyInstance()参数类型: 真实对象的类加载器, 真实对象实现的所有接口的数组, 和一个执行器
     *@返回值
     */
    SaleComputer o = (SaleComputer) Proxy.newProxyInstance(dell.getClass().getClassLoader(), dell.getClass().getInterfaces(), new InvocationHandler() {
        /**
         *@描述  对于代理对象的执行方法都会执行invoke方法,
         *@参数    proxy:就是我们的代理对象
         *         method:在反射中调用的方法会封装成Method对象,
         *         args:方法的参数数组 --invoke = method.invoke(dell, args);
         *         调用方法的时候,
         *@返回值
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //调用方法
            if (method.getName().equals("sale")) {
                //增强参数
                Double money = (Double) args[0];
                money *= 0.8;
                //在方法之前增强方法
                System.out.println("专车接送");
                String invoke = (String) method.invoke(dell, money);
                //在方法之后增强方法
                System.out.println("送货上门");
                //增强方法的方返回值
                return invoke+"键盘套装";
            }else{
                Object invoke = method.invoke(dell, args);
                return invoke;
            }

        }

    });
//       动态代理增强方法
        String sale1 = o.sale(9999.0);
        System.out.println(sale1);
    }
}`

g过滤敏感词汇

@WebFilter("/*")
public class SensitiveWordFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //1.创建代理对象,增强getParameter方法

        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 {
                //增强getParameter方法
                //判断是否是getParameter方法
                if(method.getName().equals("getParameter")){
                    //增强返回值
                    //获取返回值
                    String value = (String) method.invoke(req,args);
                    if(value != null){
                        for (String str : list) {
                            if(value.contains(str)){
                                value = value.replaceAll(str,"***");
                            }
                        }
                    }

                    return  value;
                }

                //判断方法名是否是 getParameterMap

                //判断方法名是否是 getParameterValue

                return method.invoke(req,args);
            }
        });

        //2.放行
        chain.doFilter(proxy_req, resp);
    }
    private List list = new ArrayList();//敏感词汇集合
    public void init(FilterConfig config) throws ServletException {

        try{
            //1.获取文件真实路径
            ServletContext servletContext = config.getServletContext();
            String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
            //2.读取文件
            BufferedReader br = new BufferedReader(new FileReader(realPath));
            //3.将文件的每一行数据添加到list中
            String line = null;
            while((line = br.readLine())!=null){
                list.add(line);
            }

            br.close();

            System.out.println(list);

        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public void destroy() {
    }

}`

监听器Listener


1. 事件监听机制(事件  事件源, 监听器 )
2. 注册监听:将事件事件源监听器绑定在一起,当事件源发生某事件的时候,执行监听器代码
3. ServletContextListenter(对象)
    1. 使用注解的方式配置
    1. `@WebListener("/servletContextListenerDemo")
        public class ServletContextListenterDemo implements ServletContextListener {
            @Override
            public void contextInitialized(ServletContextEvent servletContextEvent) {
                //在服务器启动会自动调用
                //通常用来加载资源文件
                ServletContext servletContext = servletContextEvent.getServletContext();
                String realPath = servletContext.getRealPath("获取在web.xml中配置的资源路径 t通常用来加载全局的资源文件");
            }

            @Override
            public void contextDestroyed(ServletContextEvent servletContextEvent) {
            //在服务器正常关闭后 ,被执行,销毁
            }
        }`
    3.使用Web.xml配置
         
         com.liangxin.web.Filter.FilterDemo1
         

你可能感兴趣的:(Java,ee,开发)