- 浏览: 3853 次
- 性别:
- 来自: 苏州
最新评论
写在前面 :使用jetty已经很久了,它是一个很出色的web容器和工具,特在此和大家分享jetty6的知识。网络上有一些关于jetty的资料,但过去陈旧且不具有系统性,导致很多人误解jetty的功能,国外目前也没有关于jetty的书籍,所以那些搞翻译的人也没有翻译来源,故决定写一本关于jetty6的书,以推广jetty在国内的使用。记住jetty不仅仅是一个web容器!
作者 :陈汝烨
由于这一些系列文章正在编写过程中,写好一章就发一章,难免有很多错误的地方,欢迎哥们指正!
第4章 Jetty服务配置文件
首先让我们回顾一下jetty的启动。命令“ java -jar start.jar etc/jetty.xml” 中指定的文件 etc/jetty.xml 就是我们本章讨论的主要对象,我们称这种文件叫“服务配置文件”。下文中有时候我们说jetty.xml配置文件并不是特指这个文件而是通指“服务配置文件”。
Jetty其实提供一个IOC/DI(反转控制和依赖注射)容器,jetty.xml配置文件就是这个容器的配置文件,和Jetty本身服务没有直接关系,你甚至可以独立使用该组件。由次可见Jetty组件化设计发挥到了极致,组件之间也没有多少依赖性。相信熟悉springframework的朋友都知道它是 IOC领域的佼佼者之一。有趣的是虽然Jetty的IOC容器实现只是在内部使用,但它却是在springframework之前就存在了。Jetty的IOC容器实现代码非常少,只涉及到两个类:
org.mortbay.xml.XmlConfiguration
org.mortbay.xml.XmlParser
其本质是解析服务配置文件的组件为我们提供一个动态调用Java代码的工具,Jetty利用这个工具实现所谓的IOC容器配置Server对象和相关组件。如果我们手写这些jetty.xml配置对应的Java代码的话,其实就是嵌入式使用Jetty的方法,这里也体现了Jetty设计精妙之处。
在本章节中我们先展示下Jetty默认的jetty.xml文件,让大家对它有关大概的了解;然后详细介绍jetty xml Configuration的语法;最后我们使用org.mortbay.xml.XmlConfiguration编写写测试用例来更深入的了解jetty.xml和jetty启动配置过程。
4.1 jetty.xml 示例剖析
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<!-- 配置Server对象,此时会调用org.mortbay.jetty.Server默认构造函数new一个Server -->
<Configure id="Server" class="org.mortbay.jetty.Server">
<!-- =========================================================== -->
<!-- 配置线程池 -->
<!-- =========================================================== -->
<!-- 调用当前Server对象的setThreadPool方法 -->
<Set name="ThreadPool">
<!-- new一个ThreadPool对象,作为setThreadPool方法的参数 -->
<New class="org.mortbay.thread.concurrent.ThreadPool">
<!-- 设置线程池核心线程数大小 -->
<Set name="corePoolSize">50</Set>
<!-- 设置线程池最大线程数 -->
<Set name="maximumPoolSize">50</Set>
</New>
</Set>
<!-- =========================================================== -->
<!-- 注册 connectors -->
<!-- =========================================================== -->
<!-- 调用当前Server对象的addConnector方法 -->
<Call name="addConnector">
<Arg> <!--Arg 标签表示addConnector方法的参数列表-->
<!--new一个SelectChannelConnector对象-->
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<!-- 调用当前SelectChannelConnector对象的setHost方法,
host表示Connector需要监听的IP地址或者hostname,
SystemProperty标签用来获取Java系统变量。
-->
<Set name="host"><SystemProperty name="jetty.host" /></Set>
<!-- 监听端口 -->
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
<!-- 一个连接的最大空闲时间 -->
<Set name="maxIdleTime">30000</Set>
<!-- Acceptor线程数量,Accepto的功能是接收客户端连接然后分配个ThreadPool处理-->
<Set name="Acceptors">2</Set>
<!-- 是否开启统计功能 -->
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<!-- 连接数量达到该数值时,Jetty会认为服务器资源已被耗尽 -->
<Set name="lowResourcesConnections">5000</Set>
<!-- 当资源饱和时,连接最大等待时间,时间单位是毫秒 -->
<Set name="lowResourcesMaxIdleTime">5000</Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- 设置Handlers -->
<!-- =========================================================== -->
<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>
<Item>
<!-- DefaultHandler 如果前一Handler没有处理request的话就会执行它。用来输出提示信息或者输出网站图标 -->
<New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
</Item>
<!-- 请求日志记录器 -->
<Item>
<New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<!-- =========================================================== -->
<!-- Configure the context deployer -->
<!-- A context deployer will deploy contexts described in -->
<!-- configuration files discovered in a directory. -->
<!-- The configuration directory can be scanned for hot -->
<!-- deployments at the configured scanInterval. -->
<!-- -->
<!-- This deployer is configured to deploy contexts configured -->
<!-- in the $JETTY_HOME/contexts directory -->
<!-- -->
<!-- =========================================================== -->
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.ContextDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
<Set name="scanInterval">5</Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Configure the webapp deployer. -->
<!-- A webapp deployer will deploy standard webapps discovered -->
<!-- in a directory at startup, without the need for additional -->
<!-- configuration files. It does not support hot deploy or -->
<!-- non standard contexts (see ContextDeployer above). -->
<!-- -->
<!-- This deployer is configured to deploy webapps from the -->
<!-- $JETTY_HOME/webapps directory -->
<!-- -->
<!-- Normally only one type of deployer need be used. -->
<!-- -->
<!-- =========================================================== -->
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.WebAppDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
<Set name="parentLoaderPriority">false</Set>
<Set name="extract">true</Set>
<Set name="allowDuplicates">false</Set>
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Configure Authentication Realms -->
<!-- Realms may be configured for the entire server here, or -->
<!-- they can be configured for a specific web app in a context -->
<!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
<!-- example). -->
<!-- =========================================================== -->
<Set name="UserRealms">
<Array type="org.mortbay.jetty.security.UserRealm">
<Item>
<New class="org.mortbay.jetty.security.HashUserRealm">
<Set name="name">Test Realm</Set>
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
<Set name="refreshInterval">0</Set>
</New>
</Item>
</Array>
</Set>
<!-- =========================================================== -->
<!-- Configure Request Log -->
<!-- Request logs may be configured for the entire server here, -->
<!-- or they can be configured for a specific web app in a -->
<!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
<!-- for an example). -->
<!-- =========================================================== -->
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
<Set name="filename"><SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Set>
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">false</Set>
<Set name="logCookies">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
<!-- =========================================================== -->
<!-- 其他配置选项 -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="gracefulShutdown">1000</Set>
</Configure>
4.2 Jetty xml Configuration语法
jetty.xml 的xml语法就好比一个编程语言,几乎就是Java语言的xml编程形式。
<Configure> 标签
<Configure>标签作为jetty.xml根元素,表示org.mortbay.xml.XmlConfiguration需要配置的对象。
属性
id:可选;如果XmlConfiguration上下文环境 中存在该ID的话就对已存在的对象进行配置,反之创建一个class属性指定的类对象,同时以id为key保存在上下文环境中。
(其实所谓的上下文环境 就是java.util.HashMap<String,Object> 对象)
class:必选;被配置的类。
可包含其他标签 :
New, Set, Put, Call 和 Ref
例子 :
<Configure id="Server" class="org.mortbay.jetty.Server" >
<Set name="port" >8080</Set>
</Configure>
指定ID属性后,通过命令java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml 启动多个配置文件时,这些配置文件都会对同一Server对象进行配置。
这段xml对应的java代码是
org.mortbay.jetty.Server server = new org.mortbay.jetty.Server(); server.setPort(8080);
<Set>标签
设置目标对象的属性(property),目标对象是Set标签的父标签所指的对象。如果name属性为xxx,那么就会调用目标对象的setXxx方法,如果setXxx方法不存在就会直接设置xxx属性字段。
如果标签内容是普通文本,那么它会尽量尝试转型,如setXxx(int xxx)就会转成相应的int行。
属性
name: 对象的属性名称
可包含对象
不同文本, Call, New and SystemProperty,Ref 标签
普通文本也可以和其他四个标签混合使用,所得的值是字符串相加的结果。
示例
<New class="foo.Bar" >
<Set name="xxx" >jetty</Set>
<Set name="cat" >
<New class="foo.Cat"></New>
<Call name="doSomething"></Call>
</Set>
</New>
等价于Java代码:
foo.Bar bar = new foo.Bar();
bar.setXxxDepartment("jetty" );
foo.Cat temp = new foo.Cat();
temp.doSomething();
bar.setCat(temp);
<Get>标签
返回目标对象的属性。假如name属性为xxx,则调用目标对象的getXxx方法,如果getXxx方法不存在,那么就直接访问xxx字段。
属性
id: 如果设置id属性,那么get获得的对象将以id值为key保存在 上下文环境
name:目标对象的属性名。
class:如果指定该属性,则调用该类上的静态的get方法或者字段。
可包含对象
Set, Put 和 Call
get所取得的对象将作为这3个标签的目标对象。
示例
<Configure class= "foo.Bar" >
<Get id= "xid" name= "xxx" />
</Configure>
等价Java代码:
//
foo.Bar bar = new foo.Bar();
x = bar.getXxx();
env.put("xid",x);//env 为上下文环境 对象
<Configure id= "Server" class= "org.mortbay.jetty.Server" >
<Call id= "s" name= "toString" />
<Call class= "org.mortbay.log.Log" name= "info" > <Arg> <Ref id= "s" /> </Arg> </Call>
</Configure>
等价Java代码:
Server server = new org.mortbay.jetty.Server();
String s = server.toString();
env.put("s",s);//env 为上下文环境 对象
org.mortbay.log.Log.info(env.get("s"));
<Put>标签
该标签是用来实现Map接口的对象上,调用Map接口的put(Object key,Object value)方法。
属性
name:必选;作为put方法的key参数
type: 可选;如果设置一个类型,那么会进行类型检查。
可包含对象
普通 文本, Call , New , SystemProperty 标签
普通文本也可以和其他三个标签混合使用,所得的值是字符串相加的结果。
这些内容或者标签所产生、返回的对象作为put(Object key,Object value)方法的value参数
示例
<Put name="admin" > admin</Put>
<Put name="obj" type="java.lang.Object" >
<New class="java.lang.Object"></New>
</Put>
<Call>标签
Call标签会调用目标对象的方法或者调用指定Class的静态方法。Call标签是通过name属性和<Arg>标签存在个数来确定哪个方法被调用。
属性
name:必选;指定调用的方法的方法名
class: 可选;如果设置该属性,则会调用该Class对象的静态方法
可包含对象
0..*个<Arg>标签,然后后面可跟随Set , Put ,Call标签, 这三个标签的目标对象便是Call标签所调用方法的返回对象。
示例
<Configure class="org.mortbay.jetty.Server ">
<Call name="doSomething">
<Arg>xx</Arg>
<Set name="key">value<Set>
</Call>
</Configure>
等级Java代码:
Server server = new Server();
Object x = server.doSomething("xx");
x.setKey("value")
如果使用class属性
<Configure class="org.mortbay.jetty.Server ">
<Call name="doSomething" class="foo.bar.Utils">
<Arg>xx</Arg>
<Set name="key">value<Set>
</Call>
</Configure>
等级Java代码:
Object x = foo.bar.Utils.doSomething("xx");
x.setKey("value")
<Arg>标签
在New和Call标签中使用,为它们确定参数列表。Arg标签还可以通过type属性来强制参数类型。
属性
type:可选;如果指定该值,那么会强制该参数对象的类型
可包含对象
普通文本 , Call , New , SystemProperty,Ref
普通文本也可以和其他四个标签混合使用,所得的值是字符串相加的结果。
示例
<Call class="foo.Bar" name="doSomething" >
<Arg>
<New class="foo.Bar2" >
<Arg>11</Arg>
</New>
</Arg>
<Arg>
<New class="foo.Bar3" >
<Arg>aa</Arg>
</New>
</Arg>
</Call>
等价于Java代码:
foo.Bar.doSomething(new foo.Bar2(11),new foo.Bar3("aa"));
<New>标签
作用和Java关键字“new”一样,调用构造方法来新建一个对象。
属性
id:可选;如果设置id,那么被创建的对象会以id为key保存在 上下文环境中
class: 必选;指明新建对象的类型。
可包含对象
0..*个<Arg>标签,然后后面可跟随Set , Put ,Call标签, 这三个标签的目标对象便是New标签所新建的对象。
Arg标签用来确定使用哪个构造方法。
示例
<New class= "foo.Bar" />
等价于Java代码:
foo.Bar bar = new foo.Bar() //调用默认构造方法
<New class= "foo.Bar" >
<Arg>bar</Arg>
</New>
等价于Java代码:
foo.Bar bar = new foo.Bar( "bar" )
<Ref>标签
从上下文环境 中取得指定的对象。然后使用Set,Put,Call等标签来操作该对象。还有另外一个用法是,在标签<Arg>和<Set>中使用Ref标签来引用某个对象来作为Arg或者Set的值对象,如<Set name="xxx" > <Ref id="objkey" /> </Set>。
属性
id:必选;要从 上下文环境获取对象的key
可包含对象
Set,Put,Call。
Ref所引用的对象作为这三个标签的操作对象。
示例
<Ref id="key">
<Set name="xxx">
<New class="foo.Bar">
</New>
</Set>
</Ref>
等价Java代码:
Object obj = env.get("key")//env表示上下文环境 对象
obj.SetXxx(new foo.Bar())
<Array>标签
创建一个List对象。当Set,Put或Arg标签需要使用List对象时,该标签就会派上用场。用Item来表示一个数组元素,并且Array只能包含Item标签。
属性
type:必选;用来指定数组元素的类型。
id:可选;如果存在id属性,那么被创建的List对象会以id值为key保存在 上下文环境中 。
可包含对象
Item标签
示例
<Array id= "plusConfig" type= "java.lang. String " > <Item>org.mortbay.jetty.webapp.WebInfConfiguration</Item> <Item>org.mortbay.jetty.plus.webapp.EnvConfiguration</Item> <Item>org.mortbay.jetty.plus.webapp.Configuration</Item> <Item>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</Item> <Item>org.mortbay.jetty.webapp.TagLibConfiguration</Item>
</Array>
等价Java代码:
List plusConfig = new ArrayList();
plusConfig.add(" org.mortbay.jetty.webapp.WebInfConfiguration ");
plusConfig.add(" org.mortbay.jetty.plus.webapp.EnvConfiguration ");
plusConfig.add(" org.mortbay.jetty.plus.webapp.Configuration ");
plusConfig.add(" org.mortbay.jetty.webapp.JettyWebXmlConfiguration ");
plusConfig.add(" org.mortbay.jetty.webapp.TagLibConfiguration ");
env.put("plusConfig ",plusConfig ); //env表示上下文环境 对象
<Map> <Entry> 标签
和Array类似,Map标签是用来创建一个HashMap对象。我们这样使用:
<Map>
<Entry>
<Item> keyName </Item>
<Item>value </Item>
</Entry>
</Map>
Entry标签包含了两个Item,第一个Item包含的内容为key,第二个为value。
对应的Java代码:
java.util.Map map = new java.util.Map();
map.put("keyName","value");
属性
id: 可选;如果存在id属性,那么被创建的List对象会以id值为key保存在 上下文环境中 。
可包含对象
两个Item标签
<Item>标签
Item被用作Array标签和Map的Entry标签中。
属性
type:可选;如果指定该值,那么会强制该参数对象的类型
可包含对象
普通文本, Call , New , SystemProperty
普通文本也可以和其他三个标签混合使用,所得的值是字符串相加的结果。
<SystemProperty>标签
取得JVM的系统属性。相当于调用Java的System .getProperty("Test" ,"value" )方法。
属性
name:系统属性名
default:可选;当指定系统属性不存在,则返回该默认值。
示例
<New class="org.mortbay.jetty.deployer.ContextDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
<Set name="scanInterval">5</Set>
</New>
等价Java代码:
ContextDeployer deployer = new org.mortbay.jetty.deployer.ContextDeployer();
deployer.setContexts(env.get(" Contexts "));
deployer.setConfigurationDir( System.getProperty("jetty.home",".") + "/contexts" )
deployer.setScanInterval(5);
4.3 org.mortbay.xml.XmlConfiguration
要学习一个新事物最快且最有效的方式是——自己动手做实验。之前已经说过Jetty配置功能的实现代码只有两个类,那么我们可以使用它们写一些是实验程序,来帮组你更好地了解如何配置。
首先新建一个Java项目(这里我们使用Eclipse),导入 $jetty_home/lib下面的jetty-6.1.22.jar和jetty-util-6.1.22.jar两个jar包。
新建类TestObject.java
public class TestObject {
public static void printString(Object x){
System.out.println(x);
}
int port;
public void setPort(int port) {
this.port = port;
}
public int getPort() {
return port;
}
public static Map static_method() {
return new HashMap<Object, Object>();
}
public void doStringAdd(String a, String b) {
System.out.println("gogo(String a,String b)==>" + a + b);
}
public void doStringAdd() {
System.out.println("call gogo()");
}
}
新建类 ConfigTest.java
import java.net.URL;
import org.mortbay.xml.XmlConfiguration;
public class ConfigTest {
public static void main(String[] args) throws Exception {
URL url = ConfigTest.class.getClassLoader().getResource(
"configure.xml");
XmlConfiguration configuration = new XmlConfiguration(url);
TestObject testObject = (TestObject) configuration.configure();
System.out.println(configuration.getIdMap());
}
}
最后在src目录下新建文件configure.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
<Configure id="testObject" class="TestObject">
<Call name="doStringAdd">
</Call>
<Call name="doStringAdd">
<Arg> a-value </Arg>
<Arg> b-value </Arg>
</Call>
<Call id="hashmap" name="static_method" class="TestObject">
<Put name="k1">
111111111
</Put>
</Call>
<Set name="port">1</Set>
<Get id="p" name="port"></Get>
<Call name="printString" class="TestObject" >
<Arg>
<Ref id="hashmap"></Ref>
</Arg>
</Call>
</Configure>
运行ConfigTest的main方法,输出结果如下:
call gogo()
gogo(String a,String b)==>a-valueb-value
{k1=111111111}
{p=1, testObject=TestObject@913750, hashmap={k1=111111111}}
现在你可以任意修改TestObject.java 和 configure.xml文件来尝试各种标签,现在就开始动手吧。
XmlConfiguration类有个方法 getIdMap(),它返回的HashMap对象就是我们在上一节中定义的属于上下文环境 对象了。
最后调用XmlConfiguration的configure()方法,返回的结果便是Configure标签指定的TestObject类的对象了。Jetty就是这样来新建Server对象的。
现在我们来研究下Jetty是如何让多个服务配置文件组合在一起运行?如果在它们之前共享上下文环 境的HashMap对象的?来看一个XmlConfiguration的main方法里面的一段源码:
XmlConfiguration last=null;//最后一次处理的XmlConfiguration对象
Object[] obj = new Object[args.length];
for (int i = 0; i < args.length; i++)
{//循环多个配置文件
if (args[i].toLowerCase().endsWith(".properties"))
{
properties.load(Resource.newResource(args[i]).getInputStream());
}
else
{
XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL());
if (last!=null)
configuration.getIdMap().putAll(last.getIdMap());
//瞧,秘密在这里,在解析下一个配置文件的时候,把最后一次的配置文件解析过程产生的HashMap对象直接设置为初始HashMap
if (properties.size()>0)
configuration.setProperties(properties);
obj[i] = configuration.configure();
last=configuration;
}
}
原文来自:http://jimichan.iteye.com/blog/601186
作者 :陈汝烨
由于这一些系列文章正在编写过程中,写好一章就发一章,难免有很多错误的地方,欢迎哥们指正!
第4章 Jetty服务配置文件
首先让我们回顾一下jetty的启动。命令“ java -jar start.jar etc/jetty.xml” 中指定的文件 etc/jetty.xml 就是我们本章讨论的主要对象,我们称这种文件叫“服务配置文件”。下文中有时候我们说jetty.xml配置文件并不是特指这个文件而是通指“服务配置文件”。
Jetty其实提供一个IOC/DI(反转控制和依赖注射)容器,jetty.xml配置文件就是这个容器的配置文件,和Jetty本身服务没有直接关系,你甚至可以独立使用该组件。由次可见Jetty组件化设计发挥到了极致,组件之间也没有多少依赖性。相信熟悉springframework的朋友都知道它是 IOC领域的佼佼者之一。有趣的是虽然Jetty的IOC容器实现只是在内部使用,但它却是在springframework之前就存在了。Jetty的IOC容器实现代码非常少,只涉及到两个类:
org.mortbay.xml.XmlConfiguration
org.mortbay.xml.XmlParser
其本质是解析服务配置文件的组件为我们提供一个动态调用Java代码的工具,Jetty利用这个工具实现所谓的IOC容器配置Server对象和相关组件。如果我们手写这些jetty.xml配置对应的Java代码的话,其实就是嵌入式使用Jetty的方法,这里也体现了Jetty设计精妙之处。
在本章节中我们先展示下Jetty默认的jetty.xml文件,让大家对它有关大概的了解;然后详细介绍jetty xml Configuration的语法;最后我们使用org.mortbay.xml.XmlConfiguration编写写测试用例来更深入的了解jetty.xml和jetty启动配置过程。
4.1 jetty.xml 示例剖析
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<!-- 配置Server对象,此时会调用org.mortbay.jetty.Server默认构造函数new一个Server -->
<Configure id="Server" class="org.mortbay.jetty.Server">
<!-- =========================================================== -->
<!-- 配置线程池 -->
<!-- =========================================================== -->
<!-- 调用当前Server对象的setThreadPool方法 -->
<Set name="ThreadPool">
<!-- new一个ThreadPool对象,作为setThreadPool方法的参数 -->
<New class="org.mortbay.thread.concurrent.ThreadPool">
<!-- 设置线程池核心线程数大小 -->
<Set name="corePoolSize">50</Set>
<!-- 设置线程池最大线程数 -->
<Set name="maximumPoolSize">50</Set>
</New>
</Set>
<!-- =========================================================== -->
<!-- 注册 connectors -->
<!-- =========================================================== -->
<!-- 调用当前Server对象的addConnector方法 -->
<Call name="addConnector">
<Arg> <!--Arg 标签表示addConnector方法的参数列表-->
<!--new一个SelectChannelConnector对象-->
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<!-- 调用当前SelectChannelConnector对象的setHost方法,
host表示Connector需要监听的IP地址或者hostname,
SystemProperty标签用来获取Java系统变量。
-->
<Set name="host"><SystemProperty name="jetty.host" /></Set>
<!-- 监听端口 -->
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
<!-- 一个连接的最大空闲时间 -->
<Set name="maxIdleTime">30000</Set>
<!-- Acceptor线程数量,Accepto的功能是接收客户端连接然后分配个ThreadPool处理-->
<Set name="Acceptors">2</Set>
<!-- 是否开启统计功能 -->
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<!-- 连接数量达到该数值时,Jetty会认为服务器资源已被耗尽 -->
<Set name="lowResourcesConnections">5000</Set>
<!-- 当资源饱和时,连接最大等待时间,时间单位是毫秒 -->
<Set name="lowResourcesMaxIdleTime">5000</Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- 设置Handlers -->
<!-- =========================================================== -->
<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>
<Item>
<!-- DefaultHandler 如果前一Handler没有处理request的话就会执行它。用来输出提示信息或者输出网站图标 -->
<New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
</Item>
<!-- 请求日志记录器 -->
<Item>
<New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<!-- =========================================================== -->
<!-- Configure the context deployer -->
<!-- A context deployer will deploy contexts described in -->
<!-- configuration files discovered in a directory. -->
<!-- The configuration directory can be scanned for hot -->
<!-- deployments at the configured scanInterval. -->
<!-- -->
<!-- This deployer is configured to deploy contexts configured -->
<!-- in the $JETTY_HOME/contexts directory -->
<!-- -->
<!-- =========================================================== -->
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.ContextDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
<Set name="scanInterval">5</Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Configure the webapp deployer. -->
<!-- A webapp deployer will deploy standard webapps discovered -->
<!-- in a directory at startup, without the need for additional -->
<!-- configuration files. It does not support hot deploy or -->
<!-- non standard contexts (see ContextDeployer above). -->
<!-- -->
<!-- This deployer is configured to deploy webapps from the -->
<!-- $JETTY_HOME/webapps directory -->
<!-- -->
<!-- Normally only one type of deployer need be used. -->
<!-- -->
<!-- =========================================================== -->
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.WebAppDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
<Set name="parentLoaderPriority">false</Set>
<Set name="extract">true</Set>
<Set name="allowDuplicates">false</Set>
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Configure Authentication Realms -->
<!-- Realms may be configured for the entire server here, or -->
<!-- they can be configured for a specific web app in a context -->
<!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
<!-- example). -->
<!-- =========================================================== -->
<Set name="UserRealms">
<Array type="org.mortbay.jetty.security.UserRealm">
<Item>
<New class="org.mortbay.jetty.security.HashUserRealm">
<Set name="name">Test Realm</Set>
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
<Set name="refreshInterval">0</Set>
</New>
</Item>
</Array>
</Set>
<!-- =========================================================== -->
<!-- Configure Request Log -->
<!-- Request logs may be configured for the entire server here, -->
<!-- or they can be configured for a specific web app in a -->
<!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
<!-- for an example). -->
<!-- =========================================================== -->
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
<Set name="filename"><SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Set>
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">false</Set>
<Set name="logCookies">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
<!-- =========================================================== -->
<!-- 其他配置选项 -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="gracefulShutdown">1000</Set>
</Configure>
4.2 Jetty xml Configuration语法
jetty.xml 的xml语法就好比一个编程语言,几乎就是Java语言的xml编程形式。
<Configure> 标签
<Configure>标签作为jetty.xml根元素,表示org.mortbay.xml.XmlConfiguration需要配置的对象。
属性
id:可选;如果XmlConfiguration上下文环境 中存在该ID的话就对已存在的对象进行配置,反之创建一个class属性指定的类对象,同时以id为key保存在上下文环境中。
(其实所谓的上下文环境 就是java.util.HashMap<String,Object> 对象)
class:必选;被配置的类。
可包含其他标签 :
New, Set, Put, Call 和 Ref
例子 :
<Configure id="Server" class="org.mortbay.jetty.Server" >
<Set name="port" >8080</Set>
</Configure>
指定ID属性后,通过命令java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml 启动多个配置文件时,这些配置文件都会对同一Server对象进行配置。
这段xml对应的java代码是
org.mortbay.jetty.Server server = new org.mortbay.jetty.Server(); server.setPort(8080);
<Set>标签
设置目标对象的属性(property),目标对象是Set标签的父标签所指的对象。如果name属性为xxx,那么就会调用目标对象的setXxx方法,如果setXxx方法不存在就会直接设置xxx属性字段。
如果标签内容是普通文本,那么它会尽量尝试转型,如setXxx(int xxx)就会转成相应的int行。
属性
name: 对象的属性名称
可包含对象
不同文本, Call, New and SystemProperty,Ref 标签
普通文本也可以和其他四个标签混合使用,所得的值是字符串相加的结果。
示例
<New class="foo.Bar" >
<Set name="xxx" >jetty</Set>
<Set name="cat" >
<New class="foo.Cat"></New>
<Call name="doSomething"></Call>
</Set>
</New>
等价于Java代码:
foo.Bar bar = new foo.Bar();
bar.setXxxDepartment("jetty" );
foo.Cat temp = new foo.Cat();
temp.doSomething();
bar.setCat(temp);
<Get>标签
返回目标对象的属性。假如name属性为xxx,则调用目标对象的getXxx方法,如果getXxx方法不存在,那么就直接访问xxx字段。
属性
id: 如果设置id属性,那么get获得的对象将以id值为key保存在 上下文环境
name:目标对象的属性名。
class:如果指定该属性,则调用该类上的静态的get方法或者字段。
可包含对象
Set, Put 和 Call
get所取得的对象将作为这3个标签的目标对象。
示例
<Configure class= "foo.Bar" >
<Get id= "xid" name= "xxx" />
</Configure>
等价Java代码:
//
foo.Bar bar = new foo.Bar();
x = bar.getXxx();
env.put("xid",x);//env 为上下文环境 对象
<Configure id= "Server" class= "org.mortbay.jetty.Server" >
<Call id= "s" name= "toString" />
<Call class= "org.mortbay.log.Log" name= "info" > <Arg> <Ref id= "s" /> </Arg> </Call>
</Configure>
等价Java代码:
Server server = new org.mortbay.jetty.Server();
String s = server.toString();
env.put("s",s);//env 为上下文环境 对象
org.mortbay.log.Log.info(env.get("s"));
<Put>标签
该标签是用来实现Map接口的对象上,调用Map接口的put(Object key,Object value)方法。
属性
name:必选;作为put方法的key参数
type: 可选;如果设置一个类型,那么会进行类型检查。
可包含对象
普通 文本, Call , New , SystemProperty 标签
普通文本也可以和其他三个标签混合使用,所得的值是字符串相加的结果。
这些内容或者标签所产生、返回的对象作为put(Object key,Object value)方法的value参数
示例
<Put name="admin" > admin</Put>
<Put name="obj" type="java.lang.Object" >
<New class="java.lang.Object"></New>
</Put>
<Call>标签
Call标签会调用目标对象的方法或者调用指定Class的静态方法。Call标签是通过name属性和<Arg>标签存在个数来确定哪个方法被调用。
属性
name:必选;指定调用的方法的方法名
class: 可选;如果设置该属性,则会调用该Class对象的静态方法
可包含对象
0..*个<Arg>标签,然后后面可跟随Set , Put ,Call标签, 这三个标签的目标对象便是Call标签所调用方法的返回对象。
示例
<Configure class="org.mortbay.jetty.Server ">
<Call name="doSomething">
<Arg>xx</Arg>
<Set name="key">value<Set>
</Call>
</Configure>
等级Java代码:
Server server = new Server();
Object x = server.doSomething("xx");
x.setKey("value")
如果使用class属性
<Configure class="org.mortbay.jetty.Server ">
<Call name="doSomething" class="foo.bar.Utils">
<Arg>xx</Arg>
<Set name="key">value<Set>
</Call>
</Configure>
等级Java代码:
Object x = foo.bar.Utils.doSomething("xx");
x.setKey("value")
<Arg>标签
在New和Call标签中使用,为它们确定参数列表。Arg标签还可以通过type属性来强制参数类型。
属性
type:可选;如果指定该值,那么会强制该参数对象的类型
可包含对象
普通文本 , Call , New , SystemProperty,Ref
普通文本也可以和其他四个标签混合使用,所得的值是字符串相加的结果。
示例
<Call class="foo.Bar" name="doSomething" >
<Arg>
<New class="foo.Bar2" >
<Arg>11</Arg>
</New>
</Arg>
<Arg>
<New class="foo.Bar3" >
<Arg>aa</Arg>
</New>
</Arg>
</Call>
等价于Java代码:
foo.Bar.doSomething(new foo.Bar2(11),new foo.Bar3("aa"));
<New>标签
作用和Java关键字“new”一样,调用构造方法来新建一个对象。
属性
id:可选;如果设置id,那么被创建的对象会以id为key保存在 上下文环境中
class: 必选;指明新建对象的类型。
可包含对象
0..*个<Arg>标签,然后后面可跟随Set , Put ,Call标签, 这三个标签的目标对象便是New标签所新建的对象。
Arg标签用来确定使用哪个构造方法。
示例
<New class= "foo.Bar" />
等价于Java代码:
foo.Bar bar = new foo.Bar() //调用默认构造方法
<New class= "foo.Bar" >
<Arg>bar</Arg>
</New>
等价于Java代码:
foo.Bar bar = new foo.Bar( "bar" )
<Ref>标签
从上下文环境 中取得指定的对象。然后使用Set,Put,Call等标签来操作该对象。还有另外一个用法是,在标签<Arg>和<Set>中使用Ref标签来引用某个对象来作为Arg或者Set的值对象,如<Set name="xxx" > <Ref id="objkey" /> </Set>。
属性
id:必选;要从 上下文环境获取对象的key
可包含对象
Set,Put,Call。
Ref所引用的对象作为这三个标签的操作对象。
示例
<Ref id="key">
<Set name="xxx">
<New class="foo.Bar">
</New>
</Set>
</Ref>
等价Java代码:
Object obj = env.get("key")//env表示上下文环境 对象
obj.SetXxx(new foo.Bar())
<Array>标签
创建一个List对象。当Set,Put或Arg标签需要使用List对象时,该标签就会派上用场。用Item来表示一个数组元素,并且Array只能包含Item标签。
属性
type:必选;用来指定数组元素的类型。
id:可选;如果存在id属性,那么被创建的List对象会以id值为key保存在 上下文环境中 。
可包含对象
Item标签
示例
<Array id= "plusConfig" type= "java.lang. String " > <Item>org.mortbay.jetty.webapp.WebInfConfiguration</Item> <Item>org.mortbay.jetty.plus.webapp.EnvConfiguration</Item> <Item>org.mortbay.jetty.plus.webapp.Configuration</Item> <Item>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</Item> <Item>org.mortbay.jetty.webapp.TagLibConfiguration</Item>
</Array>
等价Java代码:
List plusConfig = new ArrayList();
plusConfig.add(" org.mortbay.jetty.webapp.WebInfConfiguration ");
plusConfig.add(" org.mortbay.jetty.plus.webapp.EnvConfiguration ");
plusConfig.add(" org.mortbay.jetty.plus.webapp.Configuration ");
plusConfig.add(" org.mortbay.jetty.webapp.JettyWebXmlConfiguration ");
plusConfig.add(" org.mortbay.jetty.webapp.TagLibConfiguration ");
env.put("plusConfig ",plusConfig ); //env表示上下文环境 对象
<Map> <Entry> 标签
和Array类似,Map标签是用来创建一个HashMap对象。我们这样使用:
<Map>
<Entry>
<Item> keyName </Item>
<Item>value </Item>
</Entry>
</Map>
Entry标签包含了两个Item,第一个Item包含的内容为key,第二个为value。
对应的Java代码:
java.util.Map map = new java.util.Map();
map.put("keyName","value");
属性
id: 可选;如果存在id属性,那么被创建的List对象会以id值为key保存在 上下文环境中 。
可包含对象
两个Item标签
<Item>标签
Item被用作Array标签和Map的Entry标签中。
属性
type:可选;如果指定该值,那么会强制该参数对象的类型
可包含对象
普通文本, Call , New , SystemProperty
普通文本也可以和其他三个标签混合使用,所得的值是字符串相加的结果。
<SystemProperty>标签
取得JVM的系统属性。相当于调用Java的System .getProperty("Test" ,"value" )方法。
属性
name:系统属性名
default:可选;当指定系统属性不存在,则返回该默认值。
示例
<New class="org.mortbay.jetty.deployer.ContextDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
<Set name="scanInterval">5</Set>
</New>
等价Java代码:
ContextDeployer deployer = new org.mortbay.jetty.deployer.ContextDeployer();
deployer.setContexts(env.get(" Contexts "));
deployer.setConfigurationDir( System.getProperty("jetty.home",".") + "/contexts" )
deployer.setScanInterval(5);
4.3 org.mortbay.xml.XmlConfiguration
要学习一个新事物最快且最有效的方式是——自己动手做实验。之前已经说过Jetty配置功能的实现代码只有两个类,那么我们可以使用它们写一些是实验程序,来帮组你更好地了解如何配置。
首先新建一个Java项目(这里我们使用Eclipse),导入 $jetty_home/lib下面的jetty-6.1.22.jar和jetty-util-6.1.22.jar两个jar包。
新建类TestObject.java
public class TestObject {
public static void printString(Object x){
System.out.println(x);
}
int port;
public void setPort(int port) {
this.port = port;
}
public int getPort() {
return port;
}
public static Map static_method() {
return new HashMap<Object, Object>();
}
public void doStringAdd(String a, String b) {
System.out.println("gogo(String a,String b)==>" + a + b);
}
public void doStringAdd() {
System.out.println("call gogo()");
}
}
新建类 ConfigTest.java
import java.net.URL;
import org.mortbay.xml.XmlConfiguration;
public class ConfigTest {
public static void main(String[] args) throws Exception {
URL url = ConfigTest.class.getClassLoader().getResource(
"configure.xml");
XmlConfiguration configuration = new XmlConfiguration(url);
TestObject testObject = (TestObject) configuration.configure();
System.out.println(configuration.getIdMap());
}
}
最后在src目录下新建文件configure.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
<Configure id="testObject" class="TestObject">
<Call name="doStringAdd">
</Call>
<Call name="doStringAdd">
<Arg> a-value </Arg>
<Arg> b-value </Arg>
</Call>
<Call id="hashmap" name="static_method" class="TestObject">
<Put name="k1">
111111111
</Put>
</Call>
<Set name="port">1</Set>
<Get id="p" name="port"></Get>
<Call name="printString" class="TestObject" >
<Arg>
<Ref id="hashmap"></Ref>
</Arg>
</Call>
</Configure>
运行ConfigTest的main方法,输出结果如下:
call gogo()
gogo(String a,String b)==>a-valueb-value
{k1=111111111}
{p=1, testObject=TestObject@913750, hashmap={k1=111111111}}
现在你可以任意修改TestObject.java 和 configure.xml文件来尝试各种标签,现在就开始动手吧。
XmlConfiguration类有个方法 getIdMap(),它返回的HashMap对象就是我们在上一节中定义的属于上下文环境 对象了。
最后调用XmlConfiguration的configure()方法,返回的结果便是Configure标签指定的TestObject类的对象了。Jetty就是这样来新建Server对象的。
现在我们来研究下Jetty是如何让多个服务配置文件组合在一起运行?如果在它们之前共享上下文环 境的HashMap对象的?来看一个XmlConfiguration的main方法里面的一段源码:
XmlConfiguration last=null;//最后一次处理的XmlConfiguration对象
Object[] obj = new Object[args.length];
for (int i = 0; i < args.length; i++)
{//循环多个配置文件
if (args[i].toLowerCase().endsWith(".properties"))
{
properties.load(Resource.newResource(args[i]).getInputStream());
}
else
{
XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL());
if (last!=null)
configuration.getIdMap().putAll(last.getIdMap());
//瞧,秘密在这里,在解析下一个配置文件的时候,把最后一次的配置文件解析过程产生的HashMap对象直接设置为初始HashMap
if (properties.size()>0)
configuration.setProperties(properties);
obj[i] = configuration.configure();
last=configuration;
}
}
原文来自:http://jimichan.iteye.com/blog/601186
发表评论
-
时间飞快,jetty7已经发展成熟
2014-06-17 12:38 350好久没回来更新blog了。 时间飞快,jetty7已经发展 ... -
第5章 部署Web应用程序
2014-06-17 12:09 423第5章 部署Web应用程序 当我们编写好一个web应用 ... -
Jetty6 指南和解析 第3章 Jetty构架
2014-06-16 18:04 657写在前面:使用jetty已 ... -
Jetty6 指南和解析 - 第二章 Jetty初探
2014-06-16 16:09 450写在前面:使用jetty已经很久了,它是一个很出色的web容器 ... -
Jetty6 指南书 - 第一章 Jetty介绍
2014-06-16 16:07 585[b][b]写在前面 :使用jet ...
相关推荐
jetty是什么 jetty配置 jetty使用 jetty嵌入 jetty启动 jetty部署 jetty教程 jetty嵌入式 jetty
jetty6 的很详细的讲解. 很值得借鉴
Jetty6_指南书 Jetty6_指南书 Jetty6_指南书Jetty6_指南书 Jetty6_指南书 Jetty6_指南书
jetty启动配置文件
自己写的jetty6在eclipse启动中配置说明
网络上有一些关于jetty的资料,但过去陈旧且 不具有系统性,导致很多人误解jetty的功能,国外目前也没有关于jetty的书籍,所以那些搞翻译的人也没有翻译来源,故决定写一本关于jetty6 的书,以推广jetty在国内的使用...
Jetty权威指南.pdf
JETTY启动文件配置方法.txt
jetty的xml文件配置说明
Jetty配置支持HTTPS以及受信网站证书生成方式
Jetty9 配置使用HTTPS证书,访问你的服务器更安全,更好的配置方法。
maven jetty插件配置指南。 看看就知道。
eclipse导入即可使用jetty 。当成一个project 工程
刚学jetty时发现几篇安装jetty相关指南,对初学者很有用处,上传分享下给大家。
一个jetty6.jar提供下载,比tomcat灵活
eclipse jetty插件安装文件
引入到eclipse可以直接使用Starter类运行。 包含必备jar包:jetty-6.1.26.jar,jetty-util-6.1.26,servlet的相关jar包。 jetty入门级源代码。
简单jetty配置
NULL 博文链接:https://seraph115.iteye.com/blog/436300
资源名称:Jetty6入门教程资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。