為了使動态注冊成為可能,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
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
如果你使用過像struts或struts2這類java web架構,就應該知道,在使用架構之前必須先配置應用程式。一般來說,需要通過修改部署描述符,告訴servlet容器你正在使用一個架構。例如,要想在應用程式中使用struts2,可以将以下标簽添加到部署描述符中:
<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
private string name = "wuhaixu" ;
javax.servlet.servletcontainerinitializer
initializer.myservletcontainerinitializer
myservletcontainerinitializer.java
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包壓縮
結果為: