zoukankan      html  css  js  c++  java
  • 动态加载机Servlet容器加载器

         动态加载是Servlet 3.0中的新特性,它可以实现在 不重启Web应用的情况下加载新的Web对象(Servlet、 Filter、Listener)。Servlet容器加载器也是Servlet 3.0中 的新特性,对于框架的开发者来说特别有用。

    一.动态加载

      为了实现动态加载,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 的方法初始化它:

    Servlet myServlet = createServlet(MyServlet.class);

      在创建了Web对象后,可以通过ServletContext中如 下的方法把它注册到ServletContext中(这也Servlet 3中 的新特性):

    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 对象并把这个Web对象加入到ServletContext中:

    FilterRegistration.Dynamic addFilter(java.lang.String filterName,
                    java.lang.Class<? extends Filter> filterClass)
                    FilterRegistration.Dynamic addFilter(java.lang.String filterName,
                    java.lang.String className)
                    void addListener(java.lang.Class<? extends java.util.EventListener> listenerClass)
                    void addListener(java.lang.String className)
                    ServletRegistration.Dynamic addServlet(java.lang.String
                    servletName, java.lang.String className)
                    ServletRegistration.Dynamic addServlet(java.lang.String
                    servletName, java.lang.String className)

      要创建或者增加Listener,传递给第一个addListener 方法的类需要实现以下的一个或者多个接口:

    • ServletContextAttributeListener
    • ServletRequestListener
    • ServletRequestAttributeListener
    • HttpSessionListener
    • HttpSessionAttributeListener

      如果ServletContext是用于ServletContextInitializer中 onStartup方法的参数,那么Listener也需要实现 ServletContextListener。关于startUp方法以及 ServletContextInitializer接口更多的信息

      addFilter及addServlet的方法返回值为 FilterRegistration.Dynamic及ServletRegistration. Dynamic。

      FilterRegistration.Dynamic及 ServletRegistration.Dynamic都是Registration.Dynamic的 子接口。FilterRegistration.Dynamic允许配置Filter,而 ServletRegistration.Dynamic则允许配置Servlet。

      举个例子,在app14a应用中包含了名为FirstServlet 的Servlet以及一个名为DynRegListener的Listener。这个 Servlet没有使用@WebServlet的注解,也没有使用部署 描述来声明它,而通过Listener来注册这个动态的 Servlet并让它生效 。

    FirstServlet类

    package servlet;
    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;
    
    public class FirstServlet extends HttpServlet {
        private static final long serialVersionUID = -6045338L;
        private String name;
    
        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html");
            PrintWriter writer = response.getWriter();
            writer.println("<html><head><title>First servlet" + "</title></head><body>" + name);
            writer.println("</body></head>");
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    DynRegListener类

    package listener;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.ServletRegistration;
    import javax.servlet.annotation.WebListener;
    import servlet.FirstServlet;
    
    
    @WebListener
    public class DynRegListener implements ServletContextListener{
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            
        }
        // use createServlet to obtain a Servlet instance that canbe
        // configured prior to being added to ServletContext
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            ServletContext servletContext = sce.getServletContext();
            Servlet firstServlet = null;
            try {
                firstServlet = servletContext.createServlet(FirstServlet.class);
            }catch(Exception e){
                e.printStackTrace();
            }
            if(firstServlet!=null && firstServlet instanceof FirstServlet) {
                (( FirstServlet)firstServlet).setName("Dynamically reigistered servlet");
            }
            // the servlet may not be annotated with @WebServlet
            ServletRegistration.Dynamic dynamic = servletContext.addServlet("firstServlet", firstServlet);
            dynamic.addMapping("/firstServlet");
        }
    }

    二.Servlet容器加载器

      如果使用Java Web框架,如Struts、Struts 2,则需 要在使用该框架前先对应用进行配置。典型的例子是, 通过修改部署描述来告诉Servlet容器你在使用某个框 架。例如,在应用中使用Struts 2,就要加入如下的标 签到部署描述中:

    <filter>
    <filter-name>struts2</filter-name>
    <filter-class>
    org.apache.struts2.dispatcher.ng.filter.
    ➥ StrutsPrepareAndExecuteFilter
    </filter-class>
    </filter>
    <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/ *</url-pattern>
    </filter-mapping>

      在Servlet 3中,这个步骤可以省略了。框架打包时 使用这种方法,就可以对这些Web对象实现自动初始化 了。

      Servlet容器初始化主要是通过 javax.servlet.ServletContainerInitializer这个接口。这个接 口很简单,只有一个方法:onStartup。Servlet容器中, 这个方法在任何ServletContext Litener初始化前都可能 会被调用到。

      Servlet容器初始化主要是通过 javax.servlet.ServletContainerInitializer这个接口。这个接 口很简单,只有一个方法:onStartup。Servlet容器中, 这个方法在任何ServletContext Litener初始化前都可能 会被调用到。 onStartup的定义如下

    void onStartup(java.util.Set<java.lang.Class<?>> klazz,
    ServletContext servletContext)

      举个例子,本书中的initializer.jar包就包含了Servlet 容器加载器,用于注册名为UserfulServlet的Servlet。图 中列出了initializer.jar的结构。

     

       这个库是一种插件化的框架。其中有两个重要的资 源:initializer类(如清单14.3中列出来的 initializer.MyServletContainerInitializer)以及名为 javax.servlet.ServletContainerInitializer的元文件。这个元 文件必须放在JAR包中的META-INF/services目录下。 如清单14.3所示,这个文件只有一行: ServletContainerInitializer的实现类名。

    ServletContainerInitializer

    package initializer;
    import java.util.Set;
    import javax.servlet.ServletContainerInitializer;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRegistration;
    import javax.servlet.annotation.HandlesTypes;
    import servlet.UsefulServlet;
    @HandlesTypes({UsefulServlet.class})
    public class MyServletContainerInitializer implements
    ServletContainerInitializer {
    @Override
    public void onStartup(Set<Class<?>> classes, ServletContext
    servletContext) throws ServletException {
    System.out.println("onStartup");
    ServletRegistration registration =
    servletContext.addServlet("usefulServlet",
    "servlet.UsefulServlet");
    registration.addMapping("/useful");
    System.out.println("leaving onStartup");
    }
    }

    清单 javax.servlet.ServletContainerInitializer文件

    initializer.MyServletContainerInitializer

      MyServletContainerInitializer中onStartup方法的主要 任务就是注册Web对象。这个例子中,只有一个名为 UsefulServlet的Servlet对象,并绑定到/useful的路径 中。在大型框架中,注册结构可以是像Struts或者Struts 2这样的XML文档。

      ????????????????????????????????????????没搞明白

      

  • 相关阅读:
    DOM几个场景的优化场景?
    git查看commit提交的内容
    Win10 右键卡顿解决办法
    Unity4中的lightmap怎么在Unity5及其以上版本中使用
    vscode 安装了vetur插件vue html没有智能提示
    vant安装后没有样式
    docker 使用命令
    element ui 第一次点击排序为倒序
    vue强制渲染页面
    vue element el-tooltip自定义样式
  • 原文地址:https://www.cnblogs.com/jiangfeilong/p/10729161.html
Copyright © 2011-2022 走看看