• 一个简单的ServletContextListener示例


    ServletContext可以初始化String类型的参数。但是,如果你希望应用初始化参数是一个数据库DataSource呢?
    上下文参数只能是String。毕竟,你不能把一个Dog对象塞到XML部署描述文件中(事实上,可以用XML表示一个串行化对象,但是在当前的Servlet规范中还没有相关的支持……没准将来会提供)。
    如果你真的想让Web应用的所有部分都能访问一个共享的数据连接,该怎么办?
    当然可以把这个DataSource查找名放在一个上下文初始化参数里,这也是当前上下文参数最常见的一种用法。
    不过,之后谁将这个String参数转换成由Web应用各部分共享的一个具体DataSource引用呢?
    不能把这个代码放在servlet中,因为你选择谁作为第一个servlet来查找DataSource并把它存储在一个属性中呢?你真的想保证总是让某个特定的servlet最先运行吗?好好考虑一下。

    解决办法:
    可以建立一个单独的类,而不是一个servlet或JSP,它能监听ServletContext一生中的两个关键事件:初始化(创建)和撤销。这个类实现了javax.servlet.ServletContextListener。
    ServletContextListener类:

    package com.moonlit;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    public class MyServletContextListener implements ServletContextListener {
    
        @Override
        public void contextDestroyed(ServletContextEvent event) {
            // 初始化数据库连接的代码
            // and store it as a context attribute
        }
    
        @Override
        public void contextInitialized(ServletContextEvent event) {
            // 关闭数据库连接的代码
        }
    }


    教程:一个简单的ServletContextListener
    在这个例子中,我们要把String初始化参数转换成一个真正的对象——一个Dog。监听者的任务是得到有关狗的品种的上下文初始化参数(Beagle、Poodle、等等),然后使用这个String来构造一个Dog对象。监听者再把这个Dog对象存到一个ServletContext属性中,以便servlet获取。
    关键是,servlet现在能访问一个共享的数据对象(在这里,就是一个共享的Dog),而且不用读上下文对象。这个共享的对象是一个Dog还是一个数据库连接并没有关系。重点是要使用初始化参数来创建一个对象,让应用的所有部分都能共享这个对象。
    这个例子将包括如下过程:
    □ 监听者对象向ServletContextEvent对象请求应用ServletContext对象的一个引用。
    □ 监听者使用这个ServletContext引用得到"breed"上下文初始化参数,这是一个String,表示狗的品种。
    □ 监听者使用这个狗的品种String构造一个Dog对象。
    □ 监听者使用ServletContext引用在ServletContext中设置Dog属性。
    □ 这个Web应用的测试servlet从ServletContext得到Dog对象,并调用这个Dog的getBreed()方法。

    建立和使用一个上下文监听者
    要建立和使用一个上下文监听者,我们需要在web.xml中部署描述文件,在web.xml中添加如下内容:

      <listener>
        <listener-class>
          com.moonlit.MyServletContextListener
        </listener-class>
      </listener>

    除了设置ServletContextListener,我们还要设置ServletContext的初始化参数,以及测试的servlet的相关的参数。
    完整的web.xml如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <display-name>DogListenerExample</display-name>
      
      <servlet>
        <servlet-name>ListenerTester</servlet-name>
        <servlet-class>com.moonlit.ListenerTester</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>ListenerTester</servlet-name>
        <url-pattern>/ListenerTester.do</url-pattern>
      </servlet-mapping>
      
      <context-param>
        <param-name>breed</param-name>
        <param-value>Great Dane</param-value>
      </context-param>
      
      <listener>
        <listener-class>
          com.moonlit.MyServletContextListener
        </listener-class>
      </listener>
      
    </web-app>

    MyServletContextListener是监听者类。这个类实现了ServletContextListener,它得到上下文初始化参数,创建Dog,并把Dog作为一个上下文属性。
    MyServlerContextListener.java:

    package com.moonlit;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    public class MyServletContextListener implements ServletContextListener {
    
        @Override
        public void contextInitialized(ServletContextEvent event) {
            ServletContext sc = event.getServletContext();
            String dogBreed = sc.getInitParameter("breed");
            Dog d = new Dog(dogBreed);
            sc.setAttribute("dog", d);
        }
        
        @Override
        public void contextDestroyed(ServletContextEvent event) {
            // do nothing here
        }
    }

    我们需要建立一个属性类Dog。DOg只是一个普通的Java类,它的任务是作为一个属性值,由ServletContextListener实例化,并设置在ServletContext中,一遍servlet获取。
    Dog.java:

    package com.moonlit;
    
    public class Dog {
        private String breed;
        
        public Dog(String breed) {
            this.breed = breed;
        }
        
        public String getBreed() {
            return breed;
        }
    }

    ListenerTest类是一个Servlet类,它的任务是验证监听者的工作。为此这个Servlet会从上下文得到Dog属性,调用Dog的getBreed(),把结果打印到响应(使我们能在浏览器中看到)。
    ListenerTester.java:

    package com.moonlit;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @SuppressWarnings("serial")
    public class ListenerTester extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html");
            PrintWriter out = resp.getWriter();
            out.println("test context attributes set by listener<br>");
            out.println("<br>");
            Dog dog = (Dog) getServletContext().getAttribute("dog");
            out.println("Dog's breed is : " + dog == null ? "no " : dog.getBreed());
        }
    }

    效果如下:

  • 相关阅读:
    ios UIImageView
    ios UILable
    [leetCode]116. 填充每个节点的下一个右侧节点指针
    [leetCode]1002. 查找常用字符
    [leetCode]199. 二叉树的右视图
    [leetCode]784. 字母大小写全排列
    [leetCode]1297. 子串的最大出现次数
    [leetCode]1239. 串联字符串的最大长度
    1095. 山脉数组中查找目标值
    [leetCode]1235. 规划兼职工作
  • 原文地址:https://www.cnblogs.com/moonlightpoet/p/5617478.html
Copyright © 2020-2023  润新知