- 浏览: 190000 次
- 性别:
- 来自: 上海
文章分类
最新评论
jetty是一个开源、基于标准、全功能实现的Java服务器。它在Apache2.0协议下发布,因此可以自由的用于商业用途和发行。首创于1995年,Jetty受益于一个广大的用户社区,有一个稳定的核心开发者来持续专著的开发。有很多正在运行的使用Jetty的例子,这也不过是千分之十的Jetty实例。 虽然Jetty的目标很低调, 无数的站点和产品使用Jetty,但是Jetty无处不见!
Jetty可以用来:
◆一个传统的web 服务器来处理静态和动态网页;
◆最为一个专用HTTP服务器的后台来处理动态网页,就像Apache使用mod_proxy;
◆作为一个JAVA应用程序的内嵌组件。
这种灵活性意味着Jetty可以用在多种场合:
◆随产品做外盒使用,例如Tapestry, Liferay;
◆随书光盘里,用来运行例子;
◆合并到程序里提供HTTP传输,例如JXTA, MX4J;
◆集成到JavaEE服务器作为web容器,例如JOnAS, Geronimo, JBoss, JFox;
◆作为一个应用程序的组件,例如Continuum, FishEye, Maven。
Jetty的特点:
简单
Jetty的指导原则是“简单不复杂“。Jetty容易理解和使用:
◆通过API或者XML文件配置;
◆XML文件语法直接了当地在POJOs上影射API操作;
◆默认的配置文件可以使Jetty作为外盒(out-of-the-box);
◆只需少量的行数就可以嵌入一个Jetty实例。
可扩展性
在异步的WEB2.0类型的应用程序使用的技术,例如AJAX,连接停留时间要比处理一个静态页长,线程和内存需求可能急剧增长。
底层必须优雅地处理这些问题,一个低速的数据库连接可能造成站点瘫痪,因为线程被占满了。使用Jetty...
◆在高强度服务压力性能损失少;
◆在现有的web规范的框架下,能处理大用户负载,保证长时间会话的连续性;
◆整合现有聚类,例如WADI和Terracotta
高效
大量的努力用来优化代码,精炼的代码以至于漏洞尽可能少:
◆相关性尽可能少;
◆核心保持最小,附加函数放在可选包中;
◆可扩展性是一个关键问题;
◆高强度下性能衰减平缓。
嵌入性
Jetty是一个非常好的组件。这意味着很容易嵌入到一个应用程序中,而不需要应用程序去适应它:
◆使用依赖注射和反转的控制模式
插入性
Jetty被建构的适合
Jetty内建插入性。所有Jetty核心组件的实现允许不同的选择,至少一个或者更多,组件的实现总是会提供的。如果这些仍然不能满足你的要求,你可以自由的编写底层接口和抽象类最为基础。这意味着Jetty能够容易地用在一个特别的应用环境中。当Jetty在一个 JavaEE服务器中作为web容器时,这是相当有用的,Jetty的插入性保证了它和主机容器的一个紧密的集成。
转载自:http://shenpipi.spaces.live.com/Blog/cns!D36B637A9359DDC2!174.entry
Jetty是什么?
最近翻译的一篇文章
摘要:
Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。
工具箱
Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。
本文包括以下内容:
1. 嵌入式Servlet容器有什么意义?
2. 建立一个嵌入式的容器: 使用The Jetty API
3. 将配置从代码中独立出来: XML驱动的配置文件
4. 可执行的JAR包
5. 结论
6. 资源
如果让一个人说出一种开源的servlet容器,可能他们会回答Apache Tomcat。但是,Tomcat并不是孤单的,我们还有Jetty。Jetty作为可选的servlet容器只是一个额外的功能,而它真正出名是因为它是作为一个可以嵌入到其他的Java代码中的servlet容器而设计的。这就是说,开发小组将Jetty作为一组Jar文件提供出来,因此你可以在你自己的代码中将servlet容器实例化成一个对象并且可以操纵这个容器对象。
Jetty在servlet容器中算不上一个新面孔;它从1998年就已经崭露头角。Jetty的发布遵循了Apache 2.0的开源协议,你可以在免费软件和商业软件中使用Jetty而不用支付版税。
在本文中,笔者将为你为何需要嵌入式servlet容器提出一点见解,解释Jetty API的基础,并且展示如何使用XML配置文件来将Jetty的代码精简到最少。
本文的示例代码是在Jetty5.1.10以及Sun JDK 1.5.0_03下测试的。
转载时请务必保留以下作者信息和链接
作者:Ethan McCallum;shenpipi
原文:http://www.onjava.com/pub/a/onjava/2006/06/14/what-is-jetty.html
Matrix:http://www.matrix.org.cn/resource/article/44/44588_Jetty.html
关键字:Jetty
嵌入式Servlet容器的意义何在?
在你采用Jetty之前,理智的做法是首先问问自己:为什么自己的应用程序中需要嵌入一个servlet容器。 吸引我的视线的是Jetty可以为一个已经存在的应用程序提供servlet功能的能力。这种能力对于很多组织都是有用的,包括Java EE应用服务器生产商,软件测试人员以及定制软件生产商。大部分的Java开发人员都可以划分到这三种情况中。
首先,考虑要建立自己的Java EE应用服务器这样一种边缘情况。根据规范,一个完整的应用服务器必须提供servlet,EJB,以及其他一些功能。你应该采用已经存在而且测试过的组件并且使用Jetty而不是从零开始。Apache Geronimo, JBoss, 和ObjectWeb JOnAS这些项目组在建立自己Java EE应用服务器时也是这样做的。
当已经存在的容器不能满足需要的时候,软件测试人员会得益于按照需要来生成自己的servlet容器。例如,曾经有个同事想要寻找某种方式来驱动他为web service代码所写的单元测试。对于他的这种情形——几个开发人员加上几个运行在Cruise Control中的自动单元测试——我向他示范了在他的单元测试组(unit test suites)中如何动态的(on the fly)使用Jetty来实例化一个servlet容器。没有多余的脚本,没有剩余的文件,只有代码。
对于那些开发Java EE应用作为产品的人员来说,为什么仅仅提供一个WAR文件?这样你为会容器的规范而头疼,同时也会增加你的技术支持的成本。相反的,可以提供给客户一个自己具有启动,停止以及管理功能的应用程序。就连硬件生产商也会从中受益:Jetty对于普通的HTTP服务(没有servlet)只需要350k的内存,这使得可以将其用在智能设备中。你可以提供基于web的控制面板并且具有Java web应用的所有功能而不用担心那些独立的容器所带来的压力。
最后,我敢打赌嵌入式servlet容器最有趣的应用会发生在那些从来不编写传统的基于web应用的人身上。可以将Java EE和HTTP的组合作为一个C/S结构程序的后台。考虑一个事件驱动的服务,例如(假想的)Message-Driven Bank(onjava上的另外一篇文章中提到),从main()方法启动并且等待到来的请求,就像Unix中的daemon程序一样。肯定会有一些人想要将这个程序暴露成一种基于用户的风格,例如一个GUI桌面应用,这只是个时间问题。
要创建自己的基础组件,协议和socket通讯代码是最令人生厌的,而且会使人从业务逻辑中分心,就更不用说将来可能要调试的事情了。使用嵌入式的Jetty容器来将业务逻辑通过HTTP协议暴露是一个不错的选择,它不用对现有程序作过多改变。选择采用Swing,SWT,XUI这些GUI并且将请求包装成HTTP Post操作,REST,甚至SOAP来完成这个回路。与定制的特定于某个领域的协议相比,这些通用的协议可能性能稍差,但是,用不了多久,你就会从这些已经存在的经过实际检验的协议中得到好处并且节省大量的努力。
建立一个嵌入式的容器:使用Jetty API
希望以上的想法能够刺激你的胃口让你尝试一下嵌入式的servlet容器。示例程序Step1Driver 演示了一个基于Jetty的简单服务。它创建了一个servlet容器的实例,将一个servlet class映射到一个URI,并且使用一些URL来调用这个servlet。为了代码的简洁,我牺牲了一些代码的质量。
Service对象就是Jetty容器,实例化出这样一个对象就产生了一个容器。
Server service = new Server() ;
这样一来,Service对象就像一个没有门的宾馆:没有人能够进入并且使用,所以还是没有用的。接下来的一行代码设置容器在localhost,端口7501监听。
service.addListener( "localhost:7501" ) ;
为了在所有的interface上监听,不使用主机名("addListener( ":7501" )")。就像名字暗示的那样,你可以调用addListener()多次来在多个interface上监听。
注意到示例代码中维护了Server对象的一个引用,这是将来要停止容器需要用到的。
将一个web应用映射到Service是很直观的:
service.addWebApplication(
"/someContextPath" ,
"/path/to/some.war"
) ;
这个调用将处理一个web应用中的web.xml部署描述符(descriptor)来映射其中的过滤器servlet和servlet,就像其他容器所做的那样。第一个参数是context path,这个web应用的所有servlet和JSP都会被映射成相对于这个路径的URI。第二个参数是web应用本身。可以是一个打包的WAR文件或者目录格式的web应用。再次调用addWebApplication()可以用来添加其他的web应用。
注意到Jetty并不需要一个完整的符合规范的WAR文件来部署servlet。如果编写了一个搭载于HTTP协议的定制应用程序协议,你可以加载一个单一的servlet并且将其通过网络提供出去。并没有必要使用WAR文件仅仅为了使一个非web应用具有通过HTTP协议访问的功能。
为了映射这种一次性的servlet,通过在Service对象上调用getContext()动态的建立一个context。这个示例代码建立了一个叫做/embed的context。
ServletHttpContext ctx = (ServletHttpContext)
service.getContext( "/embed" ) ;
如果context不存在地话,调用getContext()将会创建一个新的context
接下来,调用addServlet()将一个servlet类映射到一个URI
ctx.addServlet(
"Simple" , // servlet name
"/TryThis/*" , // URI mapping pattern
"sample.SimpleServlet" // class name
) ;
第一个参数是该servlet的一个描述性的名字。第二个参数是要映射的路径,等同于web.xml servlet映射中的<url-pattern>。这个映射路径是相对于context path的,这里是/embed。”/*”表示这个servlet接收/embed/TryThis这样一个URI,同时它也会接收所有以此开头的URI,例如/embed/TryThis/123。在使用一个单一的servlet来作为一个大系统的入口的时候,这种映射方式非常有用。Struts和Axis就是实际应用中使用这样的映射方式的例子。
有时候你可能想让你的context成为root context,或者说“/”,这样更像一个普通的HTTP服务。Jetty通过Service.setRootWebapp()来支持此功能。
service.setRootWebapp(
"/path/to/another.war"
) ;
唯一的一个参数是一个web应用的路径。
容器在此时还是不活动的。而且它也没有试图去绑定要监听的socket,启动容器需要调用:
service.start() ;
这个方法会立即返回,因为Jetty将服务在一个独立的线程中运行。因此,当容器运行的时候,main()可以来做其他任何事情。
其余的代码是使用一组URL来调用这个嵌入式容器。这些调用确保容器已经在运行并且servlet按照期望的方式工作。
关闭容器就像启动它一样直观
service.stop() ;
注意最外层try/catch块中的catch语句。
{
service.start() ;
// ... URL calls to mapped servlet ...
service.stop() ;
}catch( Throwable t ){
System.exit( 1 ) ;
}
显示的调用System.exit()确保容器在发生异常的时候被关闭。否则,容器会持续运行因此整个应用程序也不会退出。
必须记住Jetty web应用并不限于使用代码来访问。如果我将service.stop()从刚才的代码中去掉,那么容器将一直运行并且我可以在浏览器中调用servlet,例如
http://localhost:7501/embed/TryThis/SomeExtraInfo
你并不一定要完全按照我说的去做。这个示例代码可以作为一个Eclipse项目运行。而且你也可以写一段shell脚本使其运行在Unix/Linux命令行中。在上面两种情况下,确信Jetty在你的classpath中。
将配置从代码中独立出来: XML驱动的配置文件
尽管Jetty的API非常直观简练,但是直接的调用Jetty API会将大量的配置信息——端口号,context path,servlet类名——埋藏在代码之中。Jetty提供了一种基于XML的配置方式来替代直接调用API,这样你就可以将这些配置信息都放在代码外面而使你的代码保持清洁。
Jetty的XML配置文件是基于Java反射的。java.lang.reflect中的类代表了Java中的方法和类,这样你可以实例化一个对象并且使用方法的名字和参数类型来调用它的方法。这种情况下,Jetty的XML配置文件解析器会将XML的element和属性翻译成反射方法调用。
这段节选自Step2Driver示例类中的代码是Step1Driver的一个改良版本。要是使用到了配置文件,就必须有一定的Jetty代码来加载它。
URL serviceConfig = /* load XML file */ ;
// can use an InputStream or URL
XmlConfiguration serverFactory =
new XmlConfiguration( serviceConfig ) ;
Server service =
(Server) serverFactory.newInstance() ;
不可否认,这不比Step1Driver示例节省多少代码,但是,即使你要添加新的servlet或者web应用,Step2Driver的代码不会因此而增加。而直接调用Service和context对象的方法在配置逐渐增加的情况下会越来越差。
列表1是Step2Driver加载的XML文件。顶层的<Configure> element 的属性指明了要实例化那个类。这里是Jetty Server对象。
<!-- 1 -->
<Configure class="org.mortbay.jetty.Server">
<!-- 2 -->
<Call name="addListener">
<Arg>
<!-- 3 -->
<New
class="org.mortbay.http.SocketListener">
<!-- 4 -->
<Set name="Host">
<!-- 5 -->
<SystemProperty
name="service.listen.host"
default="localhost"
/>
</Set>
<Set name="Port">
<SystemProperty
name="service.listen.port"
default="7501"
/>
</Set>
</New>
</Arg>
</Call>
<Call name="getContext">
<Arg>/embed</Arg>
<!--
call methods on the return value of
Server.getContext()
-->
<!-- 6 -->
<Call name="addServlet">
<!-- servlet name -->
<Arg>"Simple"</Arg>
<!-- URL pattern -->
<Arg>/TryThis/*</Arg>
<!-- servlet class -->
<Arg>sample.SimpleServlet</Arg>
</Call>
</Call>
</Configure>
<Call> element代表要在Server对象上调用的方法。这里要调用addListener(),如标记(2)处,它自己又有一个子element叫做<Arg>,这指明了方法的参数。这里我只能传递一个字符串值作为监听的地址,而addListener()却需要接受一个SocketListener对象作为参数。因此,我要使用<New>在标记(3)处实例化一个新的SocketListener对象。标记2和3处的代码等同于以下代码:
server.addListener(
new SocketListener( ... )
) ;
为了配置SocketListener自己,必须使用一个<Call>来调用它的setHost()方法,既然这个方法遵循了JavaBean的命名规则,示例代码因此使用了<Set> element(4)作为一种快捷方式。在后台,Jetty给set中name属性所指定的属性赋值,并且决定调用什么方法,这里是setHost()
setHost()的参数这里没有显示给出,而是使用了<SystemProperty>来从系统属性中来获取参数的值,这里从系统参数service.listen.host 和 service.listen.port。如果系统属性没有定义,你可以使用default来指定一个默认值。这里,4和5等同于以下调用:
socketListener.setHost(
System.getProperty(
"service.listen.host" ,
"localhost"
)
) ;
最后注意标记6处的<Call> element位于调用getContext方法的<Call>中。内部的<Call>是作用在外部的<Call>的返回的对象上的,这里,调用的是getServlet()返回的context上的addServlet()方法:
server.getContext().addServlet( ... ) ;
Jetty 小组的英明在于这个XML配置文件的进一步深入处理:我们可以注意到列表1中所有的Jetty特定的调用都是element和属性的值,而不是名字,这就意味着XML配置文件可以被用在任何类上,而不仅仅是Jetty的类中。根据你的应用程序的编写方式,你可以全部使用Jetty的XML配置文件来配置。
可执行JAR包
如果你使用Jetty的XML来配置你的应用,你需要使用大量的重复的代码来加载你的config文件并且运行你的应用。不过你可以使用Jetty的可执行的start.jar来为你加载文件,这会让你节省更多的代码。
例如,你可以使用以下的命令行来加载Step2Driver中的Jetty服务。
CLASSPATH= ...various Jetty JARs...
java /
-Djetty.class.path=${CLASSPATH} /
-jar <jetty install path>/start.jar /
standalone.xml
注意到这个命令仅仅加载xml文件来建立容器和监听器,因此,它并不会调用示例代码中用来测试URL的代码。
结论
一个嵌入式的Jetty servlet容器可以让你的web使用Java应用而不用打包成正式的web应用的形式。这提供了多种可能性,让Jetty成为你的工具箱中的一个多才多艺的帮手。
当然,我这里所写的东西并不能包含Jetty的所有内容。我建议你去访问Jetty的网站来获取更多的文档和示例代码。
以上转自http://jiajunde.javaeye.com/blog/373262
Jetty可以用来:
◆一个传统的web 服务器来处理静态和动态网页;
◆最为一个专用HTTP服务器的后台来处理动态网页,就像Apache使用mod_proxy;
◆作为一个JAVA应用程序的内嵌组件。
这种灵活性意味着Jetty可以用在多种场合:
◆随产品做外盒使用,例如Tapestry, Liferay;
◆随书光盘里,用来运行例子;
◆合并到程序里提供HTTP传输,例如JXTA, MX4J;
◆集成到JavaEE服务器作为web容器,例如JOnAS, Geronimo, JBoss, JFox;
◆作为一个应用程序的组件,例如Continuum, FishEye, Maven。
Jetty的特点:
简单
Jetty的指导原则是“简单不复杂“。Jetty容易理解和使用:
◆通过API或者XML文件配置;
◆XML文件语法直接了当地在POJOs上影射API操作;
◆默认的配置文件可以使Jetty作为外盒(out-of-the-box);
◆只需少量的行数就可以嵌入一个Jetty实例。
可扩展性
在异步的WEB2.0类型的应用程序使用的技术,例如AJAX,连接停留时间要比处理一个静态页长,线程和内存需求可能急剧增长。
底层必须优雅地处理这些问题,一个低速的数据库连接可能造成站点瘫痪,因为线程被占满了。使用Jetty...
◆在高强度服务压力性能损失少;
◆在现有的web规范的框架下,能处理大用户负载,保证长时间会话的连续性;
◆整合现有聚类,例如WADI和Terracotta
高效
大量的努力用来优化代码,精炼的代码以至于漏洞尽可能少:
◆相关性尽可能少;
◆核心保持最小,附加函数放在可选包中;
◆可扩展性是一个关键问题;
◆高强度下性能衰减平缓。
嵌入性
Jetty是一个非常好的组件。这意味着很容易嵌入到一个应用程序中,而不需要应用程序去适应它:
◆使用依赖注射和反转的控制模式
插入性
Jetty被建构的适合
Jetty内建插入性。所有Jetty核心组件的实现允许不同的选择,至少一个或者更多,组件的实现总是会提供的。如果这些仍然不能满足你的要求,你可以自由的编写底层接口和抽象类最为基础。这意味着Jetty能够容易地用在一个特别的应用环境中。当Jetty在一个 JavaEE服务器中作为web容器时,这是相当有用的,Jetty的插入性保证了它和主机容器的一个紧密的集成。
转载自:http://shenpipi.spaces.live.com/Blog/cns!D36B637A9359DDC2!174.entry
Jetty是什么?
最近翻译的一篇文章
摘要:
Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。
工具箱
Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。
本文包括以下内容:
1. 嵌入式Servlet容器有什么意义?
2. 建立一个嵌入式的容器: 使用The Jetty API
3. 将配置从代码中独立出来: XML驱动的配置文件
4. 可执行的JAR包
5. 结论
6. 资源
如果让一个人说出一种开源的servlet容器,可能他们会回答Apache Tomcat。但是,Tomcat并不是孤单的,我们还有Jetty。Jetty作为可选的servlet容器只是一个额外的功能,而它真正出名是因为它是作为一个可以嵌入到其他的Java代码中的servlet容器而设计的。这就是说,开发小组将Jetty作为一组Jar文件提供出来,因此你可以在你自己的代码中将servlet容器实例化成一个对象并且可以操纵这个容器对象。
Jetty在servlet容器中算不上一个新面孔;它从1998年就已经崭露头角。Jetty的发布遵循了Apache 2.0的开源协议,你可以在免费软件和商业软件中使用Jetty而不用支付版税。
在本文中,笔者将为你为何需要嵌入式servlet容器提出一点见解,解释Jetty API的基础,并且展示如何使用XML配置文件来将Jetty的代码精简到最少。
本文的示例代码是在Jetty5.1.10以及Sun JDK 1.5.0_03下测试的。
转载时请务必保留以下作者信息和链接
作者:Ethan McCallum;shenpipi
原文:http://www.onjava.com/pub/a/onjava/2006/06/14/what-is-jetty.html
Matrix:http://www.matrix.org.cn/resource/article/44/44588_Jetty.html
关键字:Jetty
嵌入式Servlet容器的意义何在?
在你采用Jetty之前,理智的做法是首先问问自己:为什么自己的应用程序中需要嵌入一个servlet容器。 吸引我的视线的是Jetty可以为一个已经存在的应用程序提供servlet功能的能力。这种能力对于很多组织都是有用的,包括Java EE应用服务器生产商,软件测试人员以及定制软件生产商。大部分的Java开发人员都可以划分到这三种情况中。
首先,考虑要建立自己的Java EE应用服务器这样一种边缘情况。根据规范,一个完整的应用服务器必须提供servlet,EJB,以及其他一些功能。你应该采用已经存在而且测试过的组件并且使用Jetty而不是从零开始。Apache Geronimo, JBoss, 和ObjectWeb JOnAS这些项目组在建立自己Java EE应用服务器时也是这样做的。
当已经存在的容器不能满足需要的时候,软件测试人员会得益于按照需要来生成自己的servlet容器。例如,曾经有个同事想要寻找某种方式来驱动他为web service代码所写的单元测试。对于他的这种情形——几个开发人员加上几个运行在Cruise Control中的自动单元测试——我向他示范了在他的单元测试组(unit test suites)中如何动态的(on the fly)使用Jetty来实例化一个servlet容器。没有多余的脚本,没有剩余的文件,只有代码。
对于那些开发Java EE应用作为产品的人员来说,为什么仅仅提供一个WAR文件?这样你为会容器的规范而头疼,同时也会增加你的技术支持的成本。相反的,可以提供给客户一个自己具有启动,停止以及管理功能的应用程序。就连硬件生产商也会从中受益:Jetty对于普通的HTTP服务(没有servlet)只需要350k的内存,这使得可以将其用在智能设备中。你可以提供基于web的控制面板并且具有Java web应用的所有功能而不用担心那些独立的容器所带来的压力。
最后,我敢打赌嵌入式servlet容器最有趣的应用会发生在那些从来不编写传统的基于web应用的人身上。可以将Java EE和HTTP的组合作为一个C/S结构程序的后台。考虑一个事件驱动的服务,例如(假想的)Message-Driven Bank(onjava上的另外一篇文章中提到),从main()方法启动并且等待到来的请求,就像Unix中的daemon程序一样。肯定会有一些人想要将这个程序暴露成一种基于用户的风格,例如一个GUI桌面应用,这只是个时间问题。
要创建自己的基础组件,协议和socket通讯代码是最令人生厌的,而且会使人从业务逻辑中分心,就更不用说将来可能要调试的事情了。使用嵌入式的Jetty容器来将业务逻辑通过HTTP协议暴露是一个不错的选择,它不用对现有程序作过多改变。选择采用Swing,SWT,XUI这些GUI并且将请求包装成HTTP Post操作,REST,甚至SOAP来完成这个回路。与定制的特定于某个领域的协议相比,这些通用的协议可能性能稍差,但是,用不了多久,你就会从这些已经存在的经过实际检验的协议中得到好处并且节省大量的努力。
建立一个嵌入式的容器:使用Jetty API
希望以上的想法能够刺激你的胃口让你尝试一下嵌入式的servlet容器。示例程序Step1Driver 演示了一个基于Jetty的简单服务。它创建了一个servlet容器的实例,将一个servlet class映射到一个URI,并且使用一些URL来调用这个servlet。为了代码的简洁,我牺牲了一些代码的质量。
Service对象就是Jetty容器,实例化出这样一个对象就产生了一个容器。
Server service = new Server() ;
这样一来,Service对象就像一个没有门的宾馆:没有人能够进入并且使用,所以还是没有用的。接下来的一行代码设置容器在localhost,端口7501监听。
service.addListener( "localhost:7501" ) ;
为了在所有的interface上监听,不使用主机名("addListener( ":7501" )")。就像名字暗示的那样,你可以调用addListener()多次来在多个interface上监听。
注意到示例代码中维护了Server对象的一个引用,这是将来要停止容器需要用到的。
将一个web应用映射到Service是很直观的:
service.addWebApplication(
"/someContextPath" ,
"/path/to/some.war"
) ;
这个调用将处理一个web应用中的web.xml部署描述符(descriptor)来映射其中的过滤器servlet和servlet,就像其他容器所做的那样。第一个参数是context path,这个web应用的所有servlet和JSP都会被映射成相对于这个路径的URI。第二个参数是web应用本身。可以是一个打包的WAR文件或者目录格式的web应用。再次调用addWebApplication()可以用来添加其他的web应用。
注意到Jetty并不需要一个完整的符合规范的WAR文件来部署servlet。如果编写了一个搭载于HTTP协议的定制应用程序协议,你可以加载一个单一的servlet并且将其通过网络提供出去。并没有必要使用WAR文件仅仅为了使一个非web应用具有通过HTTP协议访问的功能。
为了映射这种一次性的servlet,通过在Service对象上调用getContext()动态的建立一个context。这个示例代码建立了一个叫做/embed的context。
ServletHttpContext ctx = (ServletHttpContext)
service.getContext( "/embed" ) ;
如果context不存在地话,调用getContext()将会创建一个新的context
接下来,调用addServlet()将一个servlet类映射到一个URI
ctx.addServlet(
"Simple" , // servlet name
"/TryThis/*" , // URI mapping pattern
"sample.SimpleServlet" // class name
) ;
第一个参数是该servlet的一个描述性的名字。第二个参数是要映射的路径,等同于web.xml servlet映射中的<url-pattern>。这个映射路径是相对于context path的,这里是/embed。”/*”表示这个servlet接收/embed/TryThis这样一个URI,同时它也会接收所有以此开头的URI,例如/embed/TryThis/123。在使用一个单一的servlet来作为一个大系统的入口的时候,这种映射方式非常有用。Struts和Axis就是实际应用中使用这样的映射方式的例子。
有时候你可能想让你的context成为root context,或者说“/”,这样更像一个普通的HTTP服务。Jetty通过Service.setRootWebapp()来支持此功能。
service.setRootWebapp(
"/path/to/another.war"
) ;
唯一的一个参数是一个web应用的路径。
容器在此时还是不活动的。而且它也没有试图去绑定要监听的socket,启动容器需要调用:
service.start() ;
这个方法会立即返回,因为Jetty将服务在一个独立的线程中运行。因此,当容器运行的时候,main()可以来做其他任何事情。
其余的代码是使用一组URL来调用这个嵌入式容器。这些调用确保容器已经在运行并且servlet按照期望的方式工作。
关闭容器就像启动它一样直观
service.stop() ;
注意最外层try/catch块中的catch语句。
{
service.start() ;
// ... URL calls to mapped servlet ...
service.stop() ;
}catch( Throwable t ){
System.exit( 1 ) ;
}
显示的调用System.exit()确保容器在发生异常的时候被关闭。否则,容器会持续运行因此整个应用程序也不会退出。
必须记住Jetty web应用并不限于使用代码来访问。如果我将service.stop()从刚才的代码中去掉,那么容器将一直运行并且我可以在浏览器中调用servlet,例如
http://localhost:7501/embed/TryThis/SomeExtraInfo
你并不一定要完全按照我说的去做。这个示例代码可以作为一个Eclipse项目运行。而且你也可以写一段shell脚本使其运行在Unix/Linux命令行中。在上面两种情况下,确信Jetty在你的classpath中。
将配置从代码中独立出来: XML驱动的配置文件
尽管Jetty的API非常直观简练,但是直接的调用Jetty API会将大量的配置信息——端口号,context path,servlet类名——埋藏在代码之中。Jetty提供了一种基于XML的配置方式来替代直接调用API,这样你就可以将这些配置信息都放在代码外面而使你的代码保持清洁。
Jetty的XML配置文件是基于Java反射的。java.lang.reflect中的类代表了Java中的方法和类,这样你可以实例化一个对象并且使用方法的名字和参数类型来调用它的方法。这种情况下,Jetty的XML配置文件解析器会将XML的element和属性翻译成反射方法调用。
这段节选自Step2Driver示例类中的代码是Step1Driver的一个改良版本。要是使用到了配置文件,就必须有一定的Jetty代码来加载它。
URL serviceConfig = /* load XML file */ ;
// can use an InputStream or URL
XmlConfiguration serverFactory =
new XmlConfiguration( serviceConfig ) ;
Server service =
(Server) serverFactory.newInstance() ;
不可否认,这不比Step1Driver示例节省多少代码,但是,即使你要添加新的servlet或者web应用,Step2Driver的代码不会因此而增加。而直接调用Service和context对象的方法在配置逐渐增加的情况下会越来越差。
列表1是Step2Driver加载的XML文件。顶层的<Configure> element 的属性指明了要实例化那个类。这里是Jetty Server对象。
<!-- 1 -->
<Configure class="org.mortbay.jetty.Server">
<!-- 2 -->
<Call name="addListener">
<Arg>
<!-- 3 -->
<New
class="org.mortbay.http.SocketListener">
<!-- 4 -->
<Set name="Host">
<!-- 5 -->
<SystemProperty
name="service.listen.host"
default="localhost"
/>
</Set>
<Set name="Port">
<SystemProperty
name="service.listen.port"
default="7501"
/>
</Set>
</New>
</Arg>
</Call>
<Call name="getContext">
<Arg>/embed</Arg>
<!--
call methods on the return value of
Server.getContext()
-->
<!-- 6 -->
<Call name="addServlet">
<!-- servlet name -->
<Arg>"Simple"</Arg>
<!-- URL pattern -->
<Arg>/TryThis/*</Arg>
<!-- servlet class -->
<Arg>sample.SimpleServlet</Arg>
</Call>
</Call>
</Configure>
<Call> element代表要在Server对象上调用的方法。这里要调用addListener(),如标记(2)处,它自己又有一个子element叫做<Arg>,这指明了方法的参数。这里我只能传递一个字符串值作为监听的地址,而addListener()却需要接受一个SocketListener对象作为参数。因此,我要使用<New>在标记(3)处实例化一个新的SocketListener对象。标记2和3处的代码等同于以下代码:
server.addListener(
new SocketListener( ... )
) ;
为了配置SocketListener自己,必须使用一个<Call>来调用它的setHost()方法,既然这个方法遵循了JavaBean的命名规则,示例代码因此使用了<Set> element(4)作为一种快捷方式。在后台,Jetty给set中name属性所指定的属性赋值,并且决定调用什么方法,这里是setHost()
setHost()的参数这里没有显示给出,而是使用了<SystemProperty>来从系统属性中来获取参数的值,这里从系统参数service.listen.host 和 service.listen.port。如果系统属性没有定义,你可以使用default来指定一个默认值。这里,4和5等同于以下调用:
socketListener.setHost(
System.getProperty(
"service.listen.host" ,
"localhost"
)
) ;
最后注意标记6处的<Call> element位于调用getContext方法的<Call>中。内部的<Call>是作用在外部的<Call>的返回的对象上的,这里,调用的是getServlet()返回的context上的addServlet()方法:
server.getContext().addServlet( ... ) ;
Jetty 小组的英明在于这个XML配置文件的进一步深入处理:我们可以注意到列表1中所有的Jetty特定的调用都是element和属性的值,而不是名字,这就意味着XML配置文件可以被用在任何类上,而不仅仅是Jetty的类中。根据你的应用程序的编写方式,你可以全部使用Jetty的XML配置文件来配置。
可执行JAR包
如果你使用Jetty的XML来配置你的应用,你需要使用大量的重复的代码来加载你的config文件并且运行你的应用。不过你可以使用Jetty的可执行的start.jar来为你加载文件,这会让你节省更多的代码。
例如,你可以使用以下的命令行来加载Step2Driver中的Jetty服务。
CLASSPATH= ...various Jetty JARs...
java /
-Djetty.class.path=${CLASSPATH} /
-jar <jetty install path>/start.jar /
standalone.xml
注意到这个命令仅仅加载xml文件来建立容器和监听器,因此,它并不会调用示例代码中用来测试URL的代码。
结论
一个嵌入式的Jetty servlet容器可以让你的web使用Java应用而不用打包成正式的web应用的形式。这提供了多种可能性,让Jetty成为你的工具箱中的一个多才多艺的帮手。
当然,我这里所写的东西并不能包含Jetty的所有内容。我建议你去访问Jetty的网站来获取更多的文档和示例代码。
以上转自http://jiajunde.javaeye.com/blog/373262
发表评论
-
Tomcat的四种基于HTTP协议的Connector性能比较
2017-11-28 10:39 538今天在osc上看到对Tomcat的四种基于HTTP协议的Con ... -
redis 客户端 jedis
2016-11-09 15:36 509 -
高效序列化工具kryo
2016-11-09 15:29 554 -
windows7 64位下git和tortoisegit的安装和使用
2016-09-08 11:35 1559git https://github.com/git-for- ... -
Quartz 表达式
2016-08-26 15:13 383Quartz中时间表达式的设 ... -
org.apache.commons.dbutils
2016-08-26 11:20 359 -
org.quartz
2016-08-26 10:16 532 -
jedis
2016-08-24 18:08 458 -
ActiveMQ的集群多种部署方式
2016-08-15 16:56 679ActiveMQ的多种部署方式 ... -
待查看
2016-08-02 09:41 4061tair 2 tddl 3hsf 4 分库分表 pmd ... -
redis 原理
2016-07-10 14:50 8371 什么是redis redis是一个key-value存储 ... -
Notify、MetaQ、Kafka、ActiveMQ
2016-07-03 12:15 7911 Notify Notify是淘宝自主研发的一套消息服务引 ... -
Reactor、Disruptor
2016-04-27 12:55 1079Reactor 主要用于帮助开发者创建基于JVM的异步应用程序 ... -
mybatis 帮助文档
2016-04-22 11:01 509http://www.mybatis.org/mybatis- ... -
Zabbix 监控
2016-04-11 09:54 428 -
jvm实时监控工具
2016-04-09 09:35 469 -
redis学习(java调用方式)
2016-04-07 17:56 489【redis数据结构 – 简介 ... -
SonarQube代码质量管理平台安装与使用
2016-03-21 16:13 513代码质量管理工具 http://blog.csdn.net/h ... -
jboss web服务器
2016-03-17 14:15 446 -
cat监控
2016-03-16 15:22 486
相关推荐
1. **Jetty简介** - Jetty是一个开源的HTTP服务器和Servlet容器,它遵循Java Servlet和JSR-356(WebSocket)标准。 - 相比于其他服务器如Tomcat,Jetty的体积更小,启动更快,且具有低内存占用和高性能的特点。 -...
1. **Jetty简介** Jetty是一个开源、高性能的HTTP服务器和Servlet容器,它遵循Java Servlet规范,提供了对WebSocket、JSP、JSF等Web技术的支持。Jetty以其小巧、快速和高度可配置性而受到开发者喜爱,特别适合...
### Jetty简介 Jetty的主要功能是作为Servlet容器,它支持Servlet 3.1规范,这意味着它可以运行现代Java Web应用程序,包括JSP、WebSocket应用等。此外,Jetty还提供了HTTP服务器功能,可以处理静态资源、WebSocket...
1. **Jetty简介** - Jetty是一个开源的HTTP服务器和Servlet容器,支持最新的Servlet规范,如Servlet 4.0。 - 它以其轻量级、模块化的设计而著名,可以在较小的内存占用下高效运行。 2. **内嵌Jetty的优势** - **...
一、Jetty8简介 Jetty8是Jetty服务器的一个版本,它提供了对Servlet 3.0规范的支持,具有高性能、低内存占用和易于集成的特点。由于其开源性质,Jetty在开发和生产环境中都得到了广泛应用,尤其适合小型到中型的Web...
#### 一、Jetty插件简介 Jetty是一款开源、轻量级的Java应用服务器,广泛应用于开发测试环境。与Tomcat相比,Jetty具有更好的性能表现和更小的内存占用,特别是在开发过程中能够实现热部署功能,即代码修改后无需...
如果你的项目没有 `web.xml`,Jetty Runner 将尝试识别基于 Spring Boot 或其他无 XML 配置的 Web 应用。 3. 设置运行配置:在弹出的 "Edit Configurations" 窗口中,你可以配置 Jetty 的端口号、上下文路径等参数。...
Jetty以其轻量级、快速和模块化的设计而闻名,常用于小型和中型项目,尤其适合敏捷开发和持续集成。 2. **SpringMVC简介** SpringMVC是Spring框架中的一个模块,用于处理Web请求。它遵循Model-View-Controller架构...
1. **Jetty简介**:Jetty是一个Java Web服务器和Servlet容器,由Mort Bay Consulting开发。它以高性能、低内存占用和模块化架构著称,特别适合于嵌入式应用和快速开发环境。与Tomcat相比,Jetty具有更快的启动速度和...
一、Jetty简介 Jetty由Mortbay Consulting开发,最初是为了提供一个简单、快速且易于集成的Web服务器和Servlet容器。与Apache Tomcat等其他流行的Servlet容器相比,Jetty具有更小的内存占用、更快的启动时间和更...
- **多项目支持**:可以同时管理多个Jetty实例,每个实例对应不同的Web项目。 4. **安装与使用** 在Eclipse中,用户可以通过"Help" -> "Install New Software"菜单项,添加插件的更新站点,然后按照向导步骤安装...
1. Jetty简介: - Jetty是一个开源项目,由Eclipse基金会维护,其设计目标是轻量、高效、灵活,特别适合嵌入式环境。 - 它支持最新的Servlet和JSP标准,包括Servlet 4.0和JSP 2.3,同时提供了WebSocket、HTTP/2等...
Jetty项目起源于1995年,最初由Greg Wilkins创建。随着时间的发展,Jetty逐渐成为了最受欢迎的Java Web服务器之一,并于2004年成为Eclipse基金会的一部分。目前,Jetty已经发展到了第9版,持续支持最新的Java EE标准...
一、i-jetty简介 i-jetty是Jetty服务器的一个移植版,专门用于Android平台。Jetty是一款成熟的、高性能的Java HTTP服务器和Servlet容器,它以其小巧、高效和易用性著称。在Android上,i-jetty能够为应用程序提供内置...
#### 一、Jetty简介 Jetty 是一款开源的、高性能的、基于Java语言的Web服务器,它被广泛应用于开发和生产环境中。Jetty不仅体积小巧,而且功能强大,支持多种协议(如HTTP/1.1、HTTP/2、WebSocket等),并具有良好...
Jetty项目始于1995年,至今已有近30年的历史。它最初由Greg Wilkins创建,随着时间的发展逐渐成为一个成熟的Web服务器解决方案。Jetty不仅被广泛用于开发测试环境,还因其高性能和灵活性而在生产环境中得到应用。...
1. **Jetty简介** Jetty是由Eclipse基金会维护的开源项目,其设计目标是简洁、高效和可嵌入。与其他Web服务器如Tomcat相比,Jetty更注重低内存占用和快速响应,特别适合于嵌入式场景和微服务架构。 2. **安装与...
Jetty简介 Jetty是一款开源的、高性能的Java Web服务器和Servlet容器,由Eclipse基金会维护。它支持HTTP、HTTPS、WebSocket等协议,并且体积小巧,适合嵌入式环境,如Android应用。Jetty的设计理念是轻量、快速、...
#### 一、Jetty简介与入门 ##### 1.1 Jetty是什么? Jetty是一款开源的、轻量级的Java Web服务器和Java Servlet容器,由Eclipse基金会维护。它以其小巧、灵活、高性能的特点而著称,适用于开发测试环境和生产环境...