第十六章_动态注册和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传给ServletContextInitializeronStartup方法,那么监听器类也可以实现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 ? 在CODE上查看代码片 派生到我的代码片
  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.2Servlet容器初始化

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

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  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 ? 在CODE上查看代码片 派生到我的代码片
  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 ? 在CODE上查看代码片 派生到我的代码片
  1. initializer.MyServletContainerInitializer  

MyServletContainerInitializer.java

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  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包压缩



结果为:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值