第十六章_动态注册和Servlet容器初始化

16.1、动态注册

为了使动态注册成为可能,ServletContext接口中还添加了以下方法,用来动态地创建Web对象:

<T extends Filter>createFilter(Java.lang.Class<T> clazz)

<T extends java.util.EventListener> createListener(java.lang.Class<T> clazz)

<T extends Servlet> createServlet(java.lang.Class<T> clazz)

例如,假设MyServlet是一个可以直接或间接实现javax.servlet.Servlet的类,那么可以通过调用createServlet方法将MyServlet实例化:

Servlet myServlet = createServlet(MyServlet.class)

创建好一个Web对象之后,可以利用以下任意一个方法将它添加到ServletContext中,这也是Servlet3的一项新特性。

FilterRegistration.Dynamic addFilter(java.lang.String filterName, Filter filter)

<T extends java.util.EventListener> void addListener(T t)

ServletRegistration.Dynamic addServlet(java.lang.String servletName, Servlet servlet)

同样地,也可以通过在ServletContext中调用以下任意一个方法,在创建Web对象的同时,将它添加到ServletContext中。

在创建或添加监听器时,传给第一个addListener覆盖方法的类必须实现以下其中一个或多个接口:

1、ServletContextAttributeListener

2、ServletRequestListener

3、ServletRequestAttributeListener

4、HttpSessionListener

5、HttpSessionAttributeListener

如果将ServletContext传给ServletContextInitializer的onStartup方法,那么监听器类也可以实现ServletContextListener接口。

下面这个例子没有用注解,也没有用部署描述符进行声明。

 FirstServlet.java

[html] view plain copy

 print?

  1. package servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. public class FirstServlet extends HttpServlet {  
  12.   
  13.     private static final long serialVersionUID = 1L;  
  14.       
  15.     private String name ;  
  16.       
  17.     @Override  
  18.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  19.             throws ServletException, IOException {  
  20.         response.setContentType("text/html");  
  21.         PrintWriter writer = response.getWriter() ;  
  22.         writer.println("<html><head><title>First servlet" +   
  23.                 "</title></head><body>" + name);  
  24.         writer.println("</body></html>") ;  
  25.     }  
  26.     public void setName(String name) {  
  27.         this.name = name ;  
  28.     }  
  29.   
  30. }  

DynRegListener.java

[html] view plain copy

 print?

  1. package listener;  
  2.   
  3. import javax.servlet.Servlet;  
  4. import javax.servlet.ServletContext;  
  5. import javax.servlet.ServletContextEvent;  
  6. import javax.servlet.ServletContextListener;  
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.ServletRegistration;  
  9. import javax.servlet.annotation.WebListener;  
  10.   
  11. import servlet.FirstServlet;  
  12. @WebListener  
  13. public class DynRegListener implements ServletContextListener {  
  14.   
  15.     @Override  
  16.     public void contextDestroyed(ServletContextEvent arg0) {  
  17.     }  
  18.   
  19.     @Override  
  20.     public void contextInitialized(ServletContextEvent sce) {  
  21.         ServletContext servletContext = sce.getServletContext() ;  
  22.         Servlet firstServlet = null ;  
  23.         try {  
  24.             firstServlet = servletContext.createServlet(FirstServlet.class) ;  
  25.         } catch (ServletException e) {  
  26.             e.printStackTrace();  
  27.         }  
  28.         if(firstServlet != null && firstServlet instanceof FirstServlet){  
  29.             ((FirstServlet) firstServlet).setName("Dynamically registered servlet");  
  30.         }  
  31.         ServletRegistration.Dynamic dynamic = servletContext.addServlet("firstServlet", firstServlet) ;  
  32.         dynamic.addMapping("/dynamic") ;  
  33.     }  
  34.   
  35. }  

当应用程序启动时,容器会调用监听器的contextInitialized方法,结果是创建了一个FirstServlet实例,并注册和映射到/dynamic。可以利用下面这个路径访问FirstServlet

http://localhost:8080/filedowmload/dynamic

16.2、Servlet容器初始化

如果你使用过像Struts或Struts2这类Java Web框架,就应该知道,在使用框架之前必须先配置应用程序。一般来说,需要通过修改部署描述符,告诉Servlet容器你正在使用一个框架。例如,要想在应用程序中使用Struts2,可以将以下标签添加到部署描述符中:

[html] view plain copy

 print?

  1. <filter>  
  2.     <filter-name>struts2</filter-name>  
  3.     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  4. </filter>  
  5. <filter-mapping>  
  6.     <filter-name>struts2</filter-name>  
  7.     <url-pattern>/*</url-pattern>  
  8. </filter-mapping>  

但在Servlet3中,就不再需要这些了。框架可以进行打包,自动完成Web对象的首次注册。

Servlet容器初始化的核心是javax.servlet.ServletContainerInitializer接口。这是一个简单的接口,它只有一个方法:onStartup。在执行任何ServletContext监听器之前,由Servlet容器调用这个方法。

实现ServletContainerInitializer的类必须用@HandleTypes注解进行标注,以便声明初始化程序可以处理这些类型的类。

下面是个例子。要把下面的类和文件打成jar包。

FirstServlet.java

[html] view plain copy

 print?

  1. package servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. public class FirstServlet extends HttpServlet {  
  12.   
  13.     private static final long serialVersionUID = 1L;  
  14.       
  15.     private String name  = "wuhaixu" ;  
  16.       
  17.     @Override  
  18.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  19.             throws ServletException, IOException {  
  20.         response.setContentType("text/html");  
  21.         PrintWriter writer = response.getWriter() ;  
  22.         writer.println("<html><head><title>First servlet" +   
  23.                 "</title></head><body>" + name);  
  24.         writer.println("</body></html>") ;  
  25.     }  
  26.   
  27. }  

javax.servlet.ServletContainerInitializer

[html] view plain copy

 print?

  1. initializer.MyServletContainerInitializer  

MyServletContainerInitializer.java

[html] view plain copy

 print?

  1. package initializer;  
  2.   
  3. import java.util.Set;  
  4.   
  5. import javax.servlet.ServletContainerInitializer;  
  6. import javax.servlet.ServletContext;  
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.ServletRegistration;  
  9. import javax.servlet.annotation.HandlesTypes;  
  10.   
  11. import servlet.FirstServlet;  
  12. @HandlesTypes({FirstServlet.class})  
  13. public class MyServletContainerInitializer implements ServletContainerInitializer {  
  14.   
  15.     @Override  
  16.     public void onStartup(Set<Class<?>> classes, ServletContext servletContext)  
  17.             throws ServletException {  
  18.         System.out.println("onStartup");  
  19.         ServletRegistration registration = servletContext.addServlet("firstServlet", "servlet.FirstServlet");  
  20.         registration.addMapping("/f");  
  21.         System.out.println("leaving onStartup");  
  22.     }  
  23.   
  24. }  

把这些文件和类放在下面的包中,在cmd进行jar包压缩

结果为:

时间: 2024-09-08 18:21:15

第十六章_动态注册和Servlet容器初始化的相关文章

第十六章——处理锁、阻塞和死锁(3)——使用SQLServer Profiler侦测死锁

原文:第十六章--处理锁.阻塞和死锁(3)--使用SQLServer Profiler侦测死锁 前言: 作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测和处理这类问题. 死锁是当两个或者以上的事务互相阻塞引起的.在这种情况下两个事务会无限期地等待对方释放资源以便操作.下面是死锁的示意图: 本文将使用SQLServer Profiler来跟踪死锁.   准备工作: 为了侦测死锁,我们需要先模拟死锁.本例将使用两个不同的会话创建两个事务.   步骤:

python 教程 第十六章、 正则表达式

第十六章. 正则表达式 1)    匹配多个表达式 记号  re1|re2 说明  匹配正则表达式re1或re2 举例  foo|bar  匹配  foo, bar 记号  {N} 说明  匹配前面出现的正则表达式N 举例  [0-9]{3}  匹配  2)    匹配单个/多个/范围内字符 记号  . 说明  匹配任何字符(换行符除外) 举例  b.b  匹配  b和b中间有一个任意字符bab, bcb, bbb 举例  .. (匹配任何两个字符)  匹配  xx, ab 记号  [-] 说明

ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区

原文:ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区 1 用ArcMap制作地图 作为ArcGIS for Desktop的组成部分之一,ArcMap用于数据的浏览.编辑.显示.查询.地图排版等.ArcMap和ArcCatalog一起构成了完整的数据处理与管理分析的功能.在前一章中已经介绍了ArcCatalog的使用,本章中将介绍ArcMap的使用.本章的例子依然使用第4章里的小区平面图示例,但是将从原理的角度做更加

第十六章——处理锁、阻塞和死锁(1)——确定长时间运行的事务

原文:第十六章--处理锁.阻塞和死锁(1)--确定长时间运行的事务 前言: 事务是OLTP系统中的主要部分.它管理数据一致性和数据并发问题,当多个资源同时被读取或者修改相同数据时,SQLServer会通过锁定机制来确保数据库中的数据总是处于一个有效状态.在SQLServer中,锁管理器是负责实现这些锁机制.SQLServer对于不同的资源类型提供不同的锁类型,如数据库.文件.对象.表.区.页和键. 当你使用事务时,依然会遇到由事务引起的问题,这些通常是由于锁.阻塞和死锁引起的. 本系列将讲解这三

第十六章——处理锁、阻塞和死锁(2)——侦测阻塞和阻塞查询

原文:第十六章--处理锁.阻塞和死锁(2)--侦测阻塞和阻塞查询 前言: 如果一个事务正在等待一些给其他事务锁定的资源.这个事务就被成为"被阻塞的事务".反过来,引起阻塞的事务,也就是锁定资源并造成其他事务等待的事务叫做"正在阻塞的事务". 长时间运行事务会阻塞其他事务和查询,使他们等待长时间.在繁重的系统中,很多时候我们会遇到阻塞问题,如果一个事务因为阻塞未完成.会造成一些列的等待链. 本文将介绍如何发现并马上解决这方面的问题.   准备工作: 本例依旧使用SQL

《文明之光 第二册》一一第十六章 两个人的竞赛—— 苏美航天发展的历程

第十六章 两个人的竞赛-- 苏美航天发展的历程 文明之光 第二册军事的需求往往会推动科学技术的发展,而这些技术民用化之后又促进了人类文明的进步.美苏太空争霸导致了太空技术的飞速发展,而在这背后,很大程度上是两个天才的默默竞争. 1944年6月6日,军事史上最著名的D 日(D-Day).这一天,艾森豪威尔将军率领的盟军在法国诺曼底成功登陆,之后盟军迅速向纳粹占领的法国纵深推进.纳粹德国离最终的失败已为期不远了,在战争中饱受德国空军袭..

Flash基础理论课 第十六章 3D线条与填充Ⅰ

返回"Flash基础理论课 - 目录" 第十五章我们介绍了3D,但只是将物体置于3D空间中,设置大小与位置.物体实际上还是2D的.这就像老的3D游戏中,我们可以绕着某个物体或人物走,这些对象会转过来面对我们.这些物体或人物并不是真正的会转过来 -- 只是看上去是这样的,因为它们都是2D 物体,那是我们看到它唯一的一个视角. 本章,我们将真正地在 Flash中创建3D 模型.具体说来有创建并使用3D 点,线条,填充以及立体图形.学习完本章,大家就可以任意在三维空间中创建各种形状,并对它们

限制Win9X/NT系统功能二十六招_注册表

对于一些公用或专用的计算机,我们并不希望每个人都能修改系统的设定或运行其它的程序.尽管他们有时会认为自己的水平不低,但他们经常性的"偶然失手"会使你不停地忙于对系统进行维护.在这种情况下,我们就不得不想点招对系统的功能进行限制. 注册表实际是一系列数据文件,Windows 9x/NT主要通过它对硬件.软件.用户环境以及Windows的特性进行控制.在Windows 3.1时代,主要由Win.ini.System.ini及各个.ini文件完成注册表的功能.当你遇到一些入门教材不能解决的问

WF从入门到精通(第十六章):声明式工作流

学习完本章,你将掌握: 1.理解过程式(imperative)工作流模型和声明式(declarative)工作流模型之间的主要区别 2.创建声明式工作流 3.使用XAML XML词汇来创建工作流 4.调入基于XAML的工作流并执行 许多开发者或许并不知道WF既能用基于过程化的定义来执行工作流(使用工作流视图设计器)也能用基于声明式的定义来执行工作流(工作流使用XML来进行定义). 每一种风格都有优点.当你使用我们贯穿本书已使用过的技术来创建你的工作流应用程序的时候,工作流模型实际上是被编译进了一