Filter+Listener

168 阅读3分钟

日期:2021年12月6日

出处:黑马程序员JavaWeb全套教程,Java Web从基础到项目实战(IDEA版)

www.bilibili.com/video/BV1qv…

正文


Filter 过滤器

一般执行通用的操作如:登录验证、统一编码处理、敏感字符过滤...

拦截方式和生命周期

的代码演示

  • init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
  • doFilter:每一次请求被拦截资源时,会执行。执行多次
  • destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
//过滤路径为value,拦截方式dispatcherTypes
//@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.REQUEST)//拦截请求的消息
//@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.FORWARD)//拦截转发的消息
@WebFilter(value = "/index.jsp",dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST})//拦截请求和转发的消息
public class FilterDemo2 implements Filter {
    public void init(FilterConfig config) throws ServletException {
        System.out.println("init...");
    }

    public void destroy() {
        System.out.println("destroy...");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        System.out.println("doFilter...");
        chain.doFilter(request, response);
    }
}

过滤链

(多个过滤器)工作顺序是按命名的字符大小来排序的

Listener 监听器

ServletContextListener:监听ServletContext对象的创建和销毁

public class ListenerDemo1 implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {

    public ListenerDemo1() {
    }
    /*
    contextInitialized是监听ServletContext对象创建的。ServletContext对象服务器启动后自动创建
    在服务器启动后自动调用
    */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //加载资源文件
        ServletContext servletContext = sce.getServletContext();
        String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
//        获取真实路径
        String realPath = servletContext.getRealPath(contextConfigLocation);
//        加载进内存
        try {
            FileInputStream fis = new FileInputStream(realPath);
            System.out.println(fis);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("ServletContext对象被创建了...");
    }
    /*
    contextDestroyed方法在服务器关闭后,ServletContext对象被销毁。当服务器正常关闭后该方法被调用
    */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {

        System.out.println("ServletContext对象被销毁了...");
    }

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        /* Session is created. */
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        /* Session is destroyed. */
    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent sbe) {
        /* This method is called when an attribute is added to a session. */
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent sbe) {
        /* This method is called when an attribute is removed from a session. */
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent sbe) {
        /* This method is called when an attribute is replaced in a session. */
    }
}

拓展

一、uri.contains("") 判断uri中是否有指定路径

二、servletContext.getInitParameter("s:");根据对应的键获取值

三、代理模式:代理对象代理真实对象,达到增强真实对象功能的目的

动态代理

    • 增强参数
    • 增强返回值
    • 增强方法体逻辑
package Filter;
//代理对象


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTest {
    public static void main(String[] args) {
        //创建真实对象
        Hasse hasse = new Hasse();
        //动态代理增强lenovo对象(写法固定)
        SellComputer proxy_hasse = (SellComputer) Proxy.newProxyInstance(hasse.getClass().getClassLoader(), hasse.getClass().getInterfaces(), new InvocationHandler() {
/*            代理逻辑编写的方法(invoke):代理对象调用的所有方法都会触发该方法执行
                    1.proxy:代理对象
                    2.method:代理对象掉用的方法,被封装为的对象
                    3.args:代理对象调用的方法时,传递的实际参数
                    */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                System.out.println(method.getName());
//                System.out.println(args[0]);
                if (method.getName().equals("sale")){
                    //增强参数
                    double money = (double) args[0];
                    money = money * 0.85;
                    System.out.println("送货上门");
                    //使用真实对象调用方法
                    Object obj = method.invoke(hasse, money);
                    System.out.println("七天无理由退换");
                    //增强返回值
                    return obj+"和键鼠套装";
                }else {
                    Object obj = method.invoke(hasse, args);
                    //增强返回值
                    return obj;
                }
            }
        });
        //调用方法
        String sale = proxy_hasse.sale(7000);
        System.out.println(sale);
//        hasse.show();
    }
}

发现问题及解决方案

一开始以为时Listener没听懂后来有反复看了几遍发现是在contextInitialized方法中加载资源文件配置的.xml文件超纲了,这里是后面才学到的Springboot知识,所以刚开始会不明白

总结


今天主要学习了Filter过滤器,简单了解了Listener监听器,重点是理解Filter的运行逻辑,难点是拓展内容的动态代理,这个在学习到后面的框架知识有助于自己更好的理解,Listener中只学习了一个ServletContext,一开始以为时Listener没听懂后来有反复看了几遍发现是在监听器中的contextInitialized方法中加载资源文件操作里配置的.xml文件超纲了,这里是后面才学到的Springboot知识,所以刚开始会不明白