Java web 简单入门(ServletConfig和ServletContext和监听器)

此内容均为老师课上的课件内容。(写下来是为了方便以后自己查看)

在web.xml中配置ServletConfig

引入:下面这个servlet编译、布署,它的response会输出一个html页面,页面上会显示一个Email地址:

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class EmailShowServlet extends HttpServlet{
    
    public void doGet(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("lyuComputer@163.com");
    }
}

  • 上面代码属于硬编码,它把以后可能会变动的数据写到程序代码中,这种方式不好。
  • 如果将来Email地址将来发生改变,就要修改上面的servlet中的代码,然后将该servlet重新编译,重新布署。
  • 如果此Email地址是公共服务邮箱,该网站有100个servlet都要显示这个地址,那么就需要修改100个servlet,重新编译100个servlet....

解决之道:把Eamil地址写到servlet初始化参数中。

  • servlet有初始化参数,可以利用。
  • 给定一个参数名和参数值,只要把它配置在web.xmlservlet元素就行。
  • web.xml代码:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4">
  
  <servlet>
    <servlet-name>week7</servlet-name>
    <servlet-class>EmailShowServlet</servlet-class>

    <init-param>
      <param-name>adminEmail</param-name>
      <param-value>lyuComputer@163.com</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>week7</servlet-name>
    <url-pattern>/emailPage</url-pattern>
  </servlet-mapping>
</web-app>
  • servlet的代码要改一改,不用最初的硬编码,采用读取配置参数的方式。
public class EmailShowServlet extends HttpServlet{
    
    public void doGet(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        ServletConfig sc = getServletConfig();//获得ServletConfig对象
        out.println(sc.getInitParameter("adminEmail"));//注意此行的adminEmail是web.xml中的什么?
    }
}

对上面代码的解释

  • 容器初始化一个servlet时,会为这个servlet建一个唯一的ServletConfig对象。通过此对象可以获取web.xml中配置的初始化参数。
  • 容器从web.xml读出servlet初始化参数,并把这些参数交给ServletConfig,然后把ServletConfig传递给servlet的init()方法。
  • servlet初始化参数只能读一次,就是在容器初始化servlet的时候。

在web.xml中配置ServletContext

引入:上面的解决方法前进了一步,但是还有问题:

  • 如果想让Web应用的所有部分(注意:日常真正Web应用并不仅有一个servlet)都能访问这个email地址,利用上面的初始化参数,必须在配置文件中为每个servlet都要配置初始化参数。这样太麻烦了,而且可维护性很差。
  • 我们需要一个更全局的东西。

解决之道:上下文初始化参数

  • 当Tomcat启动的时候,就会创建一个ServletContext对象。它代表着当前web站点。所有servlet都共享着一个ServletContext对象,所以Servlet之间可以通过ServletContext实现通讯。
  • 所以:Web应用的所有servlet和JSP都自动能够访问上下文参数,我们不必操心为每个servlet配置,如果值有变化,只需在一个地方修改就行了。
  • 在web.xml,加上context-param元素。
<servlet>
    <servlet-name>week7</servlet-name>
    <servlet-class>EmailShowServlet</servlet-class>
</servlet>
<context-param>
    <param-name>adminEmail</param-name>
    <param-value>1125234@qq.com</param-value>
</context-param>
  • 在servlet代码中:
response.setContentType("text/html");
PrintWriter out = response.getWriter();

ServletContext sc = getServletContext();
out.println(sc.getInitParameter("adminEmail"));

上面两种方案的小总结:

  • 每个servlet有一个ServletConfig。只对本servlet可见。
  • 每个Web应用有一个ServletContext,而且Web应用中的所有部分都能访问它。所以,它是全局的。

ServletContextListener能帮我们做更多的事情

  • 刚才的实验,上下文参数只能是String类型的数据,有很大的局限性。你不能把一个Dog对象硬塞到web.xml中。
  • 思路:建立一个单独的类,它想监听上下文初始化事件,这样能得到上下文初始化参数,并在应用为客户提供服务之前运行一些代码。它能监听ServletContext一生中的两个关键事件,初始化(创建)和撤销。这个类要实现javax.servlet.ServletContextListener。

一个简单的ServletContextListener实现

  • 我们要把String初始化参数转换为一个真正的对象(一个Dog),监听者的任务是得到有关狗品种(Beagle、Poodle等)的上下文初始化参数,然后使用这个String来构造一个Dog对象。监听者再把这个Dog对象存放到一个ServletContext属性中,以便servlet获取。
  • 关键是,servlet现在能访问一个共享的应用对象(这是一个共享的Dog),而且不必读取上下文参数。
  • 重点是使用初始化参数来创建一个对象,让应用的所有部分都能共享这个对象。

建立和使用一个上下文监听者

  • 容器怎样发现和使用监听者?
  • 就像告诉容器Web应用其他部分的有关情况一样,要用同样的办法配置监听者。就是通过web.xml。
  • 过程:
    • 监听者对象向ServletContextEvent对象请求应用ServletContext对象的一个引用。
    • 监听者使用这个ServletContext引用得到"breed"的上下文初始化参数,这是一个String,表示狗的品种。
    • 监听者使用这个狗品种String构造一个Dog对象。
    • 监听者使用ServletContext引用在ServletContext中设置Dog属性。
    • 这个Web应用的测试servlet从ServletContext得到Dog对象,并调用这个Dog的getBreed()方法。(我们只是实验,想证明可以得到dog,并调用它的办法)。

建立和使用一个上下文监听者

  • 要监听ServletContext事件,需要编写一个实现ServletContextListener的监听者类,把它放在WEB-INF/classes目录中,并在部署描述文件放一个元素来告诉容器。
  • 监听者对象 类模版如下形式:
import javax.servlet.*;

public class MyServletContextListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent event){
        //Code
    }

    public void contextDestroyed(ServletContextEvent event){
        //Code
    }
}
  • web.xml加入listener元素
  <listener>
    <listener-class>
      com.example.MyServletContextListener
    </listener-class>
  </listener>

针对于上面的解决方案,开始正式创建

  • 需要3个类和一个web.xml。
  • ServletContextListener.java
    • 这个类实现了ServletContextListener,它得到上下文初始化参数,创建Dog,并把Dog设置为上下文属性。
  • Dog.java

    • Dog类只是一个普通的Java类,它的任务是作为一个属性值,由ServletContextListener实例化,并设置在ServletContext中,以便servlet获取。
  • ListenerTesterServlet.java

    • 这个类是一个Servlet,它的任务是验证监听者的工作。为此,这个Servlet会从上下文得到Dog属性,然后调用Dog的getBreed(),并把结果打印到响应(以便我们在浏览器上看到)。
import javax.servlet.*;

public class MyServletContextListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent event){
        ServletContext sc = event.getServletContext();//由事件得到ServletContext
        String dogBreed = sc.getInitParameter("breed");//使用上下文得到初始化参数
        Dog d = new Dog(dogBreed);//建立一个新的Dog
        sc.setAttribute("dog",d);//使用上下文来设置一个属性,这个属性就是Dog。现在应用的其他部分就能得到这个属性(Dog) 的值
    }

    public void contextDestroyed(ServletContextEvent event){
        //Code
    }
}
public class Dog{
    private String breed;

    public Dog(String breed){
        this.breed = breed;
    }

    public String getBreed(){
        return breed;
    }
}
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class ListenerTesterServlet extends HttpServlet{
    public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException{
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("test context attribute set by listener<br>");
        out.println("<br>");
        Dog dog = (Dog)getServletContext().getAttribute("dog");
        out.println("Dog's breed is: " + dog.getBreed());
    }
}

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4">
  
  <servlet>
    <servlet-name>ListenerTester</servlet-name>
    <servlet-class>ListenerTesterServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ListenerTester</servlet-name>
    <url-pattern>/ListenerTest.do</url-pattern>
  </servlet-mapping>
  <context-param>
    <param-name>breed</param-name>
    <param-value>Great Dane</param-value>
  </context-param>
  <listener>
    <listener-class>
      MyServletContextListener
    </listener-class>
  </listener>
</web-app>
  • 上面的代码都写完了,我们要对servlet进行编译,部署到tomcat中去。
  • 然后浏览器访问,看看可不可以。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值