天天看點

第十六章_動态注冊和Servlet容器初始化

為了使動态注冊成為可能,servletcontext接口中還添加了以下方法,用來動态地建立web對象:

<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

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 = 1l;  

    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></html>") ;  

    }  

    public void setname(string name) {  

        this.name = name ;  

}  

dynreglistener.java

第十六章_動态注冊和Servlet容器初始化

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 {  

    public void contextdestroyed(servletcontextevent arg0) {  

    public void contextinitialized(servletcontextevent sce) {  

        servletcontext servletcontext = sce.getservletcontext() ;  

        servlet firstservlet = null ;  

        try {  

            firstservlet = servletcontext.createservlet(firstservlet.class) ;  

        } catch (servletexception e) {  

            e.printstacktrace();  

        }  

        if(firstservlet != null && firstservlet instanceof firstservlet){  

            ((firstservlet) firstservlet).setname("dynamically registered servlet");  

        servletregistration.dynamic dynamic = servletcontext.addservlet("firstservlet", firstservlet) ;  

        dynamic.addmapping("/dynamic") ;  

當應用程式啟動時,容器會調用監聽器的contextinitialized方法,結果是建立了一個firstservlet執行個體,并注冊和映射到/dynamic。可以利用下面這個路徑通路firstservlet

http://localhost:8080/filedowmload/dynamic

第十六章_動态注冊和Servlet容器初始化

如果你使用過像struts或struts2這類java web架構,就應該知道,在使用架構之前必須先配置應用程式。一般來說,需要通過修改部署描述符,告訴servlet容器你正在使用一個架構。例如,要想在應用程式中使用struts2,可以将以下标簽添加到部署描述符中:

第十六章_動态注冊和Servlet容器初始化

<filter>  

    <filter-name>struts2</filter-name>  

    <filter-class>org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter</filter-class>  

</filter>  

<filter-mapping>  

    <url-pattern>/*</url-pattern>  

</filter-mapping>  

但在servlet3中,就不再需要這些了。架構可以進行打包,自動完成web對象的首次注冊。

servlet容器初始化的核心是javax.servlet.servletcontainerinitializer接口。這是一個簡單的接口,它隻有一個方法:onstartup。在執行任何servletcontext監聽器之前,由servlet容器調用這個方法。

實作servletcontainerinitializer的類必須用@handletypes注解進行标注,以便聲明初始化程式可以處理這些類型的類。

下面是個例子。要把下面的類和檔案打成jar包。

firstservlet.java

第十六章_動态注冊和Servlet容器初始化

    private string name  = "wuhaixu" ;  

javax.servlet.servletcontainerinitializer

第十六章_動态注冊和Servlet容器初始化

initializer.myservletcontainerinitializer  

myservletcontainerinitializer.java

第十六章_動态注冊和Servlet容器初始化

package initializer;  

import java.util.set;  

import javax.servlet.servletcontainerinitializer;  

import javax.servlet.annotation.handlestypes;  

@handlestypes({firstservlet.class})  

public class myservletcontainerinitializer implements servletcontainerinitializer {  

    public void onstartup(set<class<?>> classes, servletcontext servletcontext)  

            throws servletexception {  

        system.out.println("onstartup");  

        servletregistration registration = servletcontext.addservlet("firstservlet", "servlet.firstservlet");  

        registration.addmapping("/f");  

        system.out.println("leaving onstartup");  

把這些檔案和類放在下面的包中,在cmd進行jar包壓縮

第十六章_動态注冊和Servlet容器初始化
第十六章_動态注冊和Servlet容器初始化

結果為:

第十六章_動态注冊和Servlet容器初始化