静态部署
在jetty安装目录下存在一个名为webapps的目录,你可以存放web应用程序或者war文件.Jetty服务启动时会扫描webapps目录下面的文件,如果识别为web应用程序,那么就启动它。上下文路径就是文件夹的名称或者war文件的名称。(文件夹或战的名称是root,对应的上下文路径为“/”)
此类部署方式之所以被称为静态部署 ,是因为在服务器启动完成后便不在扫描webapps目录变动情况了,换句话说,在服务启动完成后,再在webapps部署新的web应用,不会及时生效,需等到服务器重启后才能被识别。
顺便提醒下,虽然这里叫静态部署,但是网络应用里面的JSP被修好后,还是会被动态重编译。
动态部署
在jetty安装目录下存在一个名为contexts的目录,在这个目录里面是用来放置动态部署的配置文件的,配置文件是xml文件,使用的语法和第4章介绍的Jetty xml配置语法相同。(配置文件语法统一,这也是jetty设计优秀之处)jetty启动服务时,会开启一个线程每隔一段时间扫描上下文目录下的xml配置文件,然后更加配置文件的内容来部署一个web应用。当服务器启动后的任意时刻,你在contexts下新增一个配置文件,jetty就会动态地启动这个web应用,同理,删除一个已存在的配置文件,jetty就会关闭相应的web应用。你也可以修改一下配置文件的最后修改时间,来达到重启web应用的功能。
此类部署方式就是所谓的动态部署了。
需要提醒的是,通常情况下你会认为部署一个网应用程序,那么这个网应用一定是符合Servlet规范的,不然jetty为什么会叫servlet容器呢!但是Jetty的设计哲学没有强迫你非得这样做,Jetty允许你发布一个支持上下文功能,但不支持的Servlet的应用。
如,在码头自带的示例中,上下文目录下有一个文件javadoc.xml,内容如下:
<?xml version =“1.0”encoding =“ISO-8859-1”?>
<!DOCTYPE配置PUBLIC“ - // Mort Bay Consulting // DTD配置// EN”“http://jetty.mortbay.org/configure.dtd”>
<! -
为javadoc配置自定义上下文。
此上下文仅包含具有默认servlet的ServletHandler
提供静态html文件和图像。
- >
<Configure class =“org.mortbay.jetty.handler.ContextHandler”>
<Call class =“org.mortbay.log.Log”name =“debug”> <Arg>配置javadoc.xml </ Arg> </ Call>
<Set name =“contextPath”> / javadoc </ Set>
<Set name =“resourceBase”> <SystemProperty name =“jetty.home”default =“。”/> / javadoc / </ Set>
<Set name =“handler”>
<New class =“org.mortbay.jetty.handler.ResourceHandler”>
<Set name =“welcomeFiles”>
<Array type =“String”>
的<item>的index.html </项目>
<Item> contents.html </ Item> <! - 未生成javadoc的索引 - >
</阵列>
</设定>
<Set name =“cacheControl”> max-age = 3600,public </ Set>
</新>
</设定>
</配置>
webapps目录和环境目录
这两个目录的位置一定必须在jetty安装目录下面么?它们的名字必须如此么?
根据前面不断宣称的Jetty的灵活性,答案肯定是否定的。目录的名称和位置只是jetty.xml文件中的默认配置,如果你愿意都可以修改。
该配置文件启动了一个java文档的网络服务,文档的静态文件被放在$ jetty_home / javadoc目录下,访问地址是http://127.0.0.1:8080/javadoc。
现在看不懂这个文件也不要紧,后续内容会设计,这里只是用来展示下Jetty的灵活性。
Jetty实现上下文功能的基本原理
在默认的服务配置文件的jetty.xml中有如下一段配置:
<! - ============================================== ============= - >
<! - 设置处理程序 - >
<! - ============================================== ============= - >
<Set name =“handler”>
<! - HandlerCollection中每一个Handler都会被按顺序执行 - >
<New id =“Handlers”class =“org.mortbay.jetty.handler.HandlerCollection”>
<Set name =“handlers”>
<Array type =“org.mortbay.jetty.Handler”>
的<item>
<! - ContextHandler的集合 - >
<New id =“Contexts”class =“org.mortbay.jetty.handler.ContextHandlerCollection”/>
</项目>
的<item>
<! - DefaultHandler如果前一Handler没有处理request的话就会执行它。用来输出提示信息或者输出网站图标 - >
<New id =“DefaultHandler”class =“org.mortbay.jetty.handler.DefaultHandler”/>
</项目>
<! - 请求日志记录器 - >
的<item>
<New id =“RequestLog”class =“org.mortbay.jetty.handler.RequestLogHandler”/>
</项目>
</阵列>
</设定>
</新>
</设定>
通过这段默认配置,为码头的服务器对象设置了一组处理程序对象,结构如下图:
Server对象将接收到的HTTP请求转发到HandlerCollection对象,再由HandlerCollection对象将HTTP请求按顺序转发给内部所有的Handler对象,即被HandlerCollection包含的对象都有机会去处理每一个请求。
让我们看一段HandlerCollection的核心代码,来验证上面的说法:
for(int i = 0; i <_handlers.length; i ++)
{
尝试
{
_handlers [i] .handle(目标,请求,响应,调度);
}
catch(IOException e)
{
扔掉;
}
catch(RuntimeException e)
{
扔掉;
}
catch(例外e)
{
if(mex == null)
mex = new MultiException();
mex.add(E);
}
}
现在来主要看本节的主角ContextHandlerCollection,通过
<新的ID = “上下文” 类= “org.mortbay.jetty.handler.ContextHandlerCollection”/>来配置,从上图中看出它也是一个集合,集合就意味着可以容纳其他处理程序,再从类名可以看出该集合只能容纳的ContextHandler类以及它的子类。新标签的ID属性被设置为“上下文”,由第4章的内容可知ContextHandlerCollection对象会以键为“上下文”保存起来,可以使用参考文献标签可以再次引用该对象,如何引用在下面的篇章会介绍。
</