WebAppContext即Web Application ContextHandler,表示一个Web应用的上下文,是上篇文章介绍的ContextHandler的一个子类,也是实际中应用的ContextHandler。先来看下类图:
可以看到在ContextHandler和WebAppContext中间还有一个ServletContxtHandler,下面就先从这个类开始分析。
1.ServletContxtHandler
ServletContextHandler是ContextHandler的直接子类,具有ContextHandler的大部分特征,不同的地方是ServletContextHandler中管理了三个Handler:ServletHandler、SessionHandler、SecurityHandler。
protected SessionHandler _sessionHandler;
protected SecurityHandler _securityHandler;
protected ServletHandler _servletHandler;
ServletHandler对ContextHandler的扩展也主要集中在对三个Handler特别是ServletHandler的管理上。SessionHandler和SecurityHandler都是可选的,ServletHandler中定义了几个常量用来表示是否需要相应的Handler。
public final static int SESSIONS=1; //需要SessionHandler
public final static int SECURITY=2; //需要SecurityHandler
public final static int NO_SESSIONS=0;//不需要SessionHandler
public final static int NO_SECURITY=0;//不需要SecurityHandler
通过 new ServletContext("/context",Context.SESSIONS|Context.NO_SECURITY);
可以配置SessionHandler和SecurityHandler。对这几个的Handler的组织是放在startContext()方法里进行的:
protected void startContext() throws Exception
{
//防止默写Handler没有正确配置,强行初始化Handler
getSessionHandler();
getSecurityHandler();
getServletHandler();
//下面是Handler链的组织过程
Handler handler = _servletHandler;
if (_securityHandler!=null)
{
_securityHandler.setHandler(handler);
handler=_securityHandler;
}
if (_sessionHandler!=null)
{
_sessionHandler.setHandler(handler);
handler=_sessionHandler;
}
// 跳过所有Wrapper类型的Handler
_wrapper=this;
while (_wrapper!=handler && _wrapper.getHandler() instanceof HandlerWrapper)
_wrapper=(HandlerWrapper)_wrapper.getHandler();
// if we are not already linked
if (_wrapper!=handler)
{
if (_wrapper.getHandler()!=null )
throw new IllegalStateException("!ScopedHandler");
_wrapper.setHandler(handler);
}
super.startContext();
//下面是ServletHandler初始化的过程
if (_servletHandler != null && _servletHandler.isStarted())
{
for (int i=_decorators.size()-1;i>=0; i--)
{
Decorator decorator = _decorators.get(i);
if (_servletHandler.getFilters()!=null)
for (FilterHolder holder:_servletHandler.getFilters())
decorator.decorateFilterHolder(holder);
if(_servletHandler.getServlets()!=null)
for (ServletHolder holder:_servletHandler.getServlets())
decorator.decorateServletHolder(holder);
}
_servletHandler.initialize();
}
}
上面最重要的工作就是形成了ServletContextHandler—>SessionHandler—>SecurityHandler—>ServletHandler的Handler链,通过这个Handler链,ServletContextHandler拿到请求之后就能依次传递给各个Handler处理,最后会通过ServletHandler转交给具体的Servlet处理。最后再这个方法里还对ServeltHandler进行了初始化。ServletHandler的initialize()方法中主要是对Filter和Servlet调用其start()方法进行启动。
ServletContextHandler中还有一些添加Servlet和Filter的方法,但实际上都是调用ServletHandler的相应方法: