zoukankan      html  css  js  c++  java
  • Java Web Servlet、监听器、过滤器、拦截器

    Java Web 监听器、过滤器、拦截器、Servlet 说明

    一:Servlet

    作用:是用Java编写的服务器端程序。
    强烈建议大家看看 https://blog.csdn.net/qq_19782019/article/details/80292110 这个大兄弟对servlet总结的很好。
    注意:web.xml 加载顺序为 context-param --》 listener --》 filter --》 servlet
    
    public class CustomHttpServlet extends HttpServlet {
    
        private CustomService customService = RegisterService.getService("CustomServiceImpl");
    
        /**
         * 覆盖 Get 方法
         * @param request
         * @param response
         */
        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("执行了doGet方法");
    
            // 证明拦截器的存在
            customService.doSomething("做点啥都行");
    
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("<h3>"+ OnlineUser.getOnlineNumber()+"</h3>");
        }
    
        /**
         * 覆盖 Post 方法
         * @param request
         * @param response
         */
        @Override
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("执行了doPost方法");
        }
    }
    

    web.xml配置

    <!-- 自定义 Http servlet-->
    <servlet>
        <servlet-name>customHttpServlet</servlet-name>
        <servlet-class>com.engraver.servlet.CustomHttpServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>customHttpServlet</servlet-name>
        <url-pattern>/custom/http/servlet</url-pattern>
    </servlet-mapping>
    
    二:监听器
    作用:监听器就是监听某个对象的的状态变化的组件。java web 监听器主要是指 ServletContextListener、HttpSessionListener、ServletRequestListener
    实现方式:实现 ServletContextListener、HttpSessionListener、ServletRequestList 中的一个接口(职责单一原则)
    ServletContextListener监听器的主要作用:
    	1、初始化的工作:初始化对象;初始化数据。比如加载数据库驱动,对连接池的初始化。
    	2、加载一些初始化的配置文件;比如spring的配置文件。
    HttpSessionListener监听Httpsession域的创建与销毁的监听器。
    ServletRequestListener监听ServletRequest域创建与销毁的监听器。ServletRequest的生命周期:每一次请求都会创建request,请求结束则销毁。
    
    /**
     * 自定义 ServletContextListener 监听器
     */
    public class CustomListener implements ServletContextListener {
    
        /**
         * 初始化
         * @param servletContextEvent
         */
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            System.out.println("监听器初始化");
    
            // 自定义注册拦截器
            RegisterInterceptor.addInterceptor(CustomInterceptor.class);
    
            // 自定义服务注册
            RegisterService.addService(CustomServiceImpl.class);
        }
    
        /**
         * 销毁
         * @param servletContextEvent
         */
        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            System.out.println("监听器销毁");
        }
    }
    
    /**
     * 自定义 HttpSessionListener 监听器
     */
    public class CustomSessionListener implements HttpSessionListener {
    
        @Override
        public void sessionCreated(HttpSessionEvent httpSessionEvent) {
            OnlineUser.add();
            System.out.println("监听Session的创建");
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
            OnlineUser.remove();
            System.out.println("监听Session的销毁");
        }
    }
    

    web.xml 配置

      <!-- 自定义监听器 -->
      <listener>
        <listener-class>com.engraver.listener.CustomListener</listener-class>
      </listener>
      <listener>
        <listener-class>com.engraver.listener.CustomSessionListener</listener-class>
      </listener>
    
    三:过滤器
    作用:filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目 标资源访问前后进行逻辑处理。
    实现方式:实现Filter接口
    
    /**
     * 自定义过滤器
     */
    public class CustomFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("自定义过滤器初始化");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws 			IOException, ServletException {
            System.out.println("自定义过滤器doFilter");
    
            System.out.println("过滤器代码");
    
            filterChain.doFilter(servletRequest,servletResponse);
    
        }
    
        @Override
        public void destroy() {
            System.out.println("自定义过滤器销毁");
        }
    }
    

    web.xml 配置

      <!-- 自定义过滤器 -->
      <filter>
        <filter-name>customFilter</filter-name>
        <filter-class>com.engraver.filter.CustomFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>customFilter</filter-name>
        <url-pattern>/custom/http/*</url-pattern>
      </filter-mapping>
    
    四:拦截器
    1、拦截器是基于java的反射机制的,而过滤器是基于函数回调。
    2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
    3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
    4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
    5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
    6、过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。过滤器包裹住servlet,servlet包裹住拦截器。
    

    Java手写拦截器实现思路:

    ​ 第一步:创建拦截器接口定义before 和 after 方法。

    ​ 第二步:创建拦截器实现类,实现before 和 after 方法具体内容。

    ​ 第三步:创建被代理类(拦截器依赖于动态代理),测试实例用为尽量还原实际开发中的情景,使用了service 和 serviceImpl 方法

    ​ 第四步:创建动态代理类,传出被代理类和拦截器类对象。

    ​ 第五步:编写拦截器注册类,利用反射机制

    ​ 第六步:编写服务注册类,在服务注册时使用单实例通过动态代理模式建实例化的动态代理类注册到服务注册表的HashMap对象内。

    ​ 第七步:在ServletContextListener监听器初始化时调用 拦截器注册 和 服务注册。

    ​ 第八步:在 Servlet 类中获取相应的动态代理服务类。调用服务类方法会触动拦截器类的 before 和 after 方法

    代码已托管于https://gitee.com/my_engraver/engraver_study.git 下的 study_web 工程。

    /**
     * @author Engraver
     * @title: InterceptorInterface
     * @description: 拦截器接口
     */
    public interface InterceptorInterface {
    
        /**
         * 方法之前
         */
        void before(Object[] args) throws Exception;
    
        /**
         * 方法之后
         */
        void after(Object[] args) throws Exception;
    }
    
    /**
     * @author Engraver
     * @title: CustomInterceptor
     * @description: 自定义拦截器
     */
    public class CustomInterceptor implements InterceptorInterface {
    
        /**
         * 方法之前
         *
         * @param args
         */
        @Override
        public void before(Object[] args) throws Exception {
            System.out.println("自定义拦截器before方法");
            // throw new IOException("拦截器中出现了问题");
        }
    
        /**
         * 方法之后
         *
         * @param args
         */
        @Override
        public void after(Object[] args) throws Exception {
            System.out.println("自定义拦截器after方法");
        }
    }
    
    /**
     * @author Engraver
     * @title: CustomService
     * @description: 自定义服务
     */
    public interface CustomService {
    
        /**
         * 想做点啥就做点啥
         * @param params
         * @return
         */
        String doSomething(String params);
    }
    
    /**
     * @author Engraver
     * @title: CustomServiceImpl
     * @description: 自定义服务实现类
     */
    public class CustomServiceImpl implements CustomService {
    
        @Override
        public String doSomething(String params){
            System.out.println("自定义服务 doSomething = " + params);
            return "操作成功了哦";
        }
    }
    
    /**
     * @author Engraver
     * @title: RegisterInterceptor
     * @description: 自定义注册拦截器
     */
    public class RegisterInterceptor {
    
        /**
         * 注册拦截表
         */
        private static Map<String,InterceptorInterface> interceptorRegedit = new HashMap<>();
    
        /**
         * 增加拦截器到注册表
         * @param tClass
         */
        public static void addInterceptor(Class< ? extends  InterceptorInterface> tClass){
            try {
                InterceptorInterface interceptorInterface = tClass.newInstance();
                interceptorRegedit.put(tClass.getSimpleName(),interceptorInterface);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
        public static InterceptorInterface getInterceptor(String key){
            return interceptorRegedit.get(key);
        }
    }
    
    /**
     * @author Engraver
     * @title: RegisterService
     * @description: 服务注册表
     */
    public class RegisterService {
    
        /**
         * 注册服务表
         */
        private static Map<String, CustomService> serviceRegedit = new HashMap<>();
    
        /**
         * 增加服务到注册表
         * @param tClass
         */
        public static void addService(Class< ? extends  CustomService> tClass){
    
            // 获取拦截器
            InterceptorInterface interceptorInterface = RegisterInterceptor.getInterceptor("CustomInterceptor");
    
            // 动态代理
            DynamicProxyHandler dynamicProxyHandler = new DynamicProxyHandler(interceptorInterface,tClass);
    
            // 生成动态代理类
            CustomService customService = dynamicProxyHandler.getProxy();
            serviceRegedit.put(tClass.getSimpleName(),customService);
    
        }
    
        public static CustomService getService(String key){
            return serviceRegedit.get(key);
        }
    }
    
    /**
     * @author Engraver
     * @title: DynamicProxyHandler
     * @description: 动态代理拦截器
     */
    public class DynamicProxyHandler implements InvocationHandler {
    
        /**
         * 拦截器
         */
        private InterceptorInterface interceptorInterface;
    
        /**
         * 被代理对象
         */
        private Object target;
    
        public DynamicProxyHandler(InterceptorInterface interceptorInterface,Class< ? extends CustomService> object) {
            this.interceptorInterface = interceptorInterface;
            try {
                this.target = object.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
            // 调用拦截器的方法
            interceptorInterface.before(args);
    
            // 调用被代理类的方法
            Object result = method.invoke(target,args);
    
            // 调用拦截器的方法
            interceptorInterface.after(args);
            return result;
        }
    
        /**
         * 获取代理对象
         * @param <T>
         * @return
         */
        public <T> T getProxy(){
            return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        }
    }
    
    public class CustomListener implements ServletContextListener {
    
        /**
         * 初始化
         * @param servletContextEvent
         */
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            System.out.println("监听器初始化");
    
            // 自定义注册拦截器
            RegisterInterceptor.addInterceptor(CustomInterceptor.class);
    
            // 自定义服务注册
            RegisterService.addService(CustomServiceImpl.class);
        }
    
        /**
         * 销毁
         * @param servletContextEvent
         */
        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            System.out.println("监听器销毁");
        }
    }
    
    /**
     * @author Engraver
     * @title: CustomHttpServlet
     * @description: 自定义Http servlet
     */
    public class CustomHttpServlet extends HttpServlet {
    
    
        private CustomService customService = RegisterService.getService("CustomServiceImpl");
    
        /**
         * 覆盖 Get 方法
         * @param request
         * @param response
         */
        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("执行了doGet方法");
    
            // 证明拦截器的存在
            customService.doSomething("做点啥都行");
    
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("<h3>"+ OnlineUser.getOnlineNumber()+"</h3>");
        }
    
        /**
         * 覆盖 Post 方法
         * @param request
         * @param response
         */
        @Override
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("执行了doPost方法");
        }
    }
    
    

    web.xml 配置

    <!-- 自定义 Http servlet-->
    <servlet>
        <servlet-name>customHttpServlet</servlet-name>
        <servlet-class>com.engraver.servlet.CustomHttpServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>customHttpServlet</servlet-name>
        <url-pattern>/custom/http/servlet</url-pattern>
    </servlet-mapping>
    
    <!-- 自定义监听器 -->
    <listener>
        <listener-class>com.engraver.listener.CustomListener</listener-class>
    </listener>
    
    学而不思则罔,思而不学则殆
  • 相关阅读:
    在线整数序列百科全书
    非常完整的线性DP及记忆化搜索讲义
    洛谷P2858 奶牛零食 题解 区间DP入门题
    HDU3394 Railway 题解(边双连通分量)
    POJ1144 Network 题解 点双连通分量(求割点数量)
    LibreOJ6279. 数列分块入门 3 题解
    LibreOJ 6278. 数列分块入门 2 题解
    LibreOJ 6277. 数列分块入门 1 题解
    洛谷P1020 导弹拦截 题解 LIS扩展题 Dilworth定理
    CF1272E. Nearest Opposite Parity 题解 广度优先搜索
  • 原文地址:https://www.cnblogs.com/engraver/p/14714897.html
Copyright © 2011-2022 走看看