尽管etc/jetty.xml设置了合理的缺省值,但为了满足你的实际需要,你仍然可以定制Jetty.Jetty的配置文件结构如下:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="Server" class="org.mortbay.jetty.Server">
<!-- required configuration -->
<!-- connectors -->
<!-- handlers -->
<!-- webapps/contexts -->
<!-- optional configuration -->
<!-- threadpool -->
<!-- session id manager -->
<!-- authentication realms -->
<!-- request logs -->
<!-- extra server options -->
</Configure>
configure.dtd内容如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
This is the document type descriptor for the
org.mortbay.XmlConfiguration class. It allows a java object to be
configured by with a sequence of Set, Put and Call elements. These tags are
mapped to methods on the object to be configured as follows:
<Set name="Test">value</Set> == obj.setTest("value");
<Put name="Test">value</Put> == obj.put("Test","value");
<Call name="test"><Arg>value</Arg></Call> == obj.test("value");
Values themselves may be configured objects that are created with the
<New> tag or returned from a <Call> tag.
Values are matched to arguments on a best effort approach, but types
my be specified if a match is not achieved.
$Id: configure_1_3.dtd,v 1.2 2005/10/26 20:48:48 gregwilkins Exp $
-->
<!ENTITY % CONFIG "Set|Get|Put|Call|New|Ref|Array|Map|Property">
<!ENTITY % VALUE "#PCDATA|Get|Call|New|Ref|Array|Map|SystemProperty|Property">
<!ENTITY % TYPEATTR "type CDATA #IMPLIED " > <!-- String|Character|Short|Byte|Integer|Long|Boolean|Float|Double|char|short|byte|int|long|boolean|float|double|URL|InetAddress|InetAddrPort| #classname -->
<!ENTITY % IMPLIEDCLASSATTR "class NMTOKEN #IMPLIED" >
<!ENTITY % CLASSATTR "class NMTOKEN #REQUIRED" >
<!ENTITY % NAMEATTR "name NMTOKEN #REQUIRED" >
<!ENTITY % DEFAULTATTR "default CDATA #IMPLIED" >
<!ENTITY % IDATTR "id NMTOKEN #IMPLIED" >
<!ENTITY % REQUIREDIDATTR "id NMTOKEN #REQUIRED" >
<!--
Configure Element.
This is the root element that specifies the class of object that
can be configured:
<Configure class="com.acme.MyClass"> ... </Configure>
-->
<!ELEMENT Configure (%CONFIG;)* >
<!ATTLIST Configure %IMPLIEDCLASSATTR; %IDATTR; >
<!--
Set Element.
This element maps to a call to a setter method or field on the current object.
The name and optional type attributes are used to select the setter
method. If the name given is xxx, then a setXxx method is used, or
the xxx field is used of setXxx cannot be found.
A Set element can contain value text and/or the value objects returned
by other elements such as Call, New, SystemProperty, etc.
If no value type is specified, then white
space is trimmed out of the value. If it contains multiple value
elements they are added as strings before being converted to any
specified type.
A Set with a class attribute is treated as a static set method invocation.
-->
<!ELEMENT Set ( %VALUE; )* >
<!ATTLIST Set %NAMEATTR; %TYPEATTR; %IMPLIEDCLASSATTR; >
<!--
Get Element.
This element maps to a call to a getter method or field on the current object.
The name attribute is used to select the get method.
If the name given is xxx, then a getXxx method is used, or
the xxx field is used if getXxx cannot be found.
A Get element can contain other elements such as Set, Put, Call, etc.
which act on the object returned by the get call.
A Get with a class attribute is treated as a static get method or field.
-->
<!ELEMENT Get (%CONFIG;)*>
<!ATTLIST Get %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR; >
<!--
Put Element.
This element maps to a call to a put method on the current object,
which must implement the Map interface. The name attribute is used
as the put key and the optional type attribute can force the type
of the value.
A Put element can contain value text and/or value elements such as Call,
New, SystemProperty, etc. If no value type is specified, then white
space is trimmed out of the value. If it contains multiple value
elements they are added as strings before being converted to any
specified type.
-->
<!ELEMENT Put ( %VALUE; )* >
<!ATTLIST Put %NAMEATTR; %TYPEATTR; >
<!--
Call Element.
This element maps to an arbitrary call to a method on the current object,
The name attribute and Arg elements are used to select the method.
A Call element can contain a sequence of Arg elements followed by
a sequence of other elements such as Set, Put, Call, etc. which act on any object
returned by the original call:
<Call id="o2" name="test">
<Arg>value1</Arg>
<Set name="Test">Value2</Set>
</Call>
This is equivalent to:
Object o2 = o1.test("value1");
o2.setTest("value2");
A Call with a class attribute is treated as a static call.
-->
<!ELEMENT Call (Arg*,(%CONFIG;)*)>
<!ATTLIST Call %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR;>
<!--
Arg Element.
This element defines a positional argument for the Call element.
The optional type attribute can force the type of the value.
An Arg element can contain value text and/or value elements such as Call,
New, SystemProperty, etc. If no value type is specified, then white
space is trimmed out of the value. If it contains multiple value
elements they are added as strings before being converted to any
specified type.
-->
<!ELEMENT Arg ( %VALUE; )* >
<!ATTLIST Arg %TYPEATTR; >
<!--
New Element.
This element allows the creation of a new object as part of a
value for elements such as Set, Put, Arg, etc. The class attribute determines
the type of the new object and the contained Arg elements
are used to select the constructor for the new object.
A New element can contain a sequence of Arg elements followed by
a sequence of elements such as Set, Put, Call, etc. elements
which act on the new object:
<New id="o" class="com.acme.MyClass">
<Arg>value1</Arg>
<Set name="test">Value2</Set>
</New>
This is equivalent to:
Object o = new com.acme.MyClass("value1");
o.setTest("Value2");
-->
<!ELEMENT New (Arg*,(%CONFIG;)*)>
<!ATTLIST New %CLASSATTR; %IDATTR;>
<!--
Ref Element.
This element allows a previously created object to be referenced by id.
A Ref element can contain a sequence of elements such as Set, Put, Call, etc.
which act on the referenced object:
<Ref id="myobject">
<Set name="Test">Value2</Set>
</New>
-->
<!ELEMENT Ref ((%CONFIG;)*)>
<!ATTLIST Ref %REQUIREDIDATTR;>
<!--
Array Element.
This element allows the creation of a new array as part of a
value of elements such as Set, Put, Arg, etc. The type attribute determines
the type of the new array and the contained Item elements
are used for each element of the array:
<Array type="java.lang.String">
<Item>value0</Item>
<Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
</Array>
This is equivalent to:
String[] a = new String[] { "value0", new String("value1") };
-->
<!ELEMENT Array (Item*)>
<!ATTLIST Array %TYPEATTR; %IDATTR; >
<!--
Map Element.
This element allows the creation of a new map as part of a
value of elements such as Set, Put, Arg, etc. The type attribute determines
the type of the new array and the contained Item elements
are used for each element of the array:
<Map>
<Entry>
<Item>keyName</Item>
<Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
</Entry>
</Map>
This is equivalent to:
Map m = new HashMap();
m.put("keyName", new String("value1"));
-->
<!ELEMENT Map (Entry*)>
<!ATTLIST Map %IDATTR; >
<!ELEMENT Entry (Item,Item)>
<!--
Item Element.
This element defines an entry for the Array or Map Entry elements.
The optional type attribute can force the type of the value.
An Item element can contain value text and/or the value object of
elements such as Call, New, SystemProperty, etc. If no value type
is specified, then white space is trimmed out of the value.
If it contains multiple value elements they are added as strings
before being converted to any specified type.
-->
<!ELEMENT Item ( %VALUE; )* >
<!ATTLIST Item %TYPEATTR; %IDATTR; >
<!--
System Property Element.
This element allows JVM System properties to be retrieved as
part of the value of elements such as Set, Put, Arg, etc.
The name attribute specifies the property name and the optional
default argument provides a default value.
<SystemProperty name="Test" default="value" />
This is equivalent to:
System.getProperty("Test","value");
-->
<!ELEMENT SystemProperty EMPTY>
<!ATTLIST SystemProperty %NAMEATTR; %DEFAULTATTR; %IDATTR;>
<!--
Property Element.
This element allows arbitrary properties to be retrieved by name.
The name attribute specifies the property name and the optional
default argument provides a default value.
A Property element can contain a sequence of elements such as Set, Put, Call, etc.
which act on the retrieved object:
<Property name="Server">
<Call id="jdbcIdMgr" name="getAttribute">
<Arg>jdbcIdMgr</Arg>
</Call>
</Property>
-->
<!ELEMENT Property ((%CONFIG;)*)>
<!ATTLIST Property %NAMEATTR; %DEFAULTATTR; %IDATTR;>
Jetty配置文件分解
Doctype(必需)
在jetty.xml中声明的所有标签和元素必须符合configure.dtd的规范。
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"
Server(必需)
org.mortbay.jetty.Server是Jetty HTTP服务器的主类。当运行服务器时,这是第一个被调用的实例。它用于整合
连接器(Connectors,HTTP请求接收者)和请求
处理器(request Handlers).server本身是一个处理器(handler)和
线程池(TreadPool).连接器使用线程池的方法来运行任务,这些任务最后将调用处理方法。
<Configure id="Server" class="org.mortbay.jetty.Server">
...
</Configure>
Connectors(必需)
实现了
org.mortbay.jetty.Connector接口的类为HTTP协议提供连接器。在其配置中,你可以设置Jetty用于监听连接请求的端口。
<Set name="connectors">
<Array type="org.mortbay.jetty.Connector">
<Item>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="host">
<SystemProperty name="jetty.host" />
</Set>
<Set name="port">
<SystemProperty name="jetty.port" default="8080"/>
</Set>
...
</New>
</Item>
</Array>
</Set>
Handlers(必需)
处理器用于处理接收到的请求。org.mortbay.jetty.webapp.WebAppContext专门用于服务web应用程序。如果不想完全成熟的应用程序,而只是想处理静态内容和一些servlets,那么你可以使用ContextHandler和配置只需要的服务。server的handlers列表可通过下面的调用来定义:
<Set name="handlers">
<Array type="org.mortbay.jetty.Handler">
...
</Set>
ThreadPool(可选)
线程池可以确保线程在运行方法退出后被线程池重用,从而避免线程创建时带来的开销。配置如下:
<Set name="ThreadPool">
<New class="org.mortbay.thread.QueuedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">200</Set>
<Set name="lowThreads">20</Set>
<Set name="SpawnOrShrinkAt">2
</Set> </New>
</Set>
Security Realm(可选)
安全域用于用户认证和授权,安全域中可配置的数量和安全域的类型对于服务器来是没有限制的。下面的示例使用etc/realm.properties文件设置安全域:
<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">etc/realm.properties</Set>
</New>
</Item>
</Array>
</Set>
示例:
所有的示例都假设是在$JETTY_HOME下,并且下面的所有配置文件都以$JETTY_HOME/etc/myjetty.xml保存。
静态部署1
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="Server" class="org.mortbay.jetty.Server">
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="port">8080</Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.mortbay.jetty.Handler">
<Item>
<New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
</Item>
</Array>
</Set>
</New>
</Set>
<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>
</New>
</Arg>
</Call>
</Configure>
启动:
java -jar start.jar etc/myjetty.xml
View your webapplications at http://localhost:8080/webappfolder/. If you have no webapp defined for the root context ("/"), visiting http://localhost:8080/ will give you a normal 404 page.
静态部署2
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="Server" class="org.mortbay.jetty.Server">
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="host"><SystemProperty name="jetty.host" /></Set>
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.mortbay.jetty.Handler">
<Item>
<New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<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>
As before, start up Jetty with this command:
java -jar start.jar etc/myjetty.xml
View your webapplications at http://localhost:8080/webappfolder/.
Other than the extra configuration settings, the biggest change is the addition of the org.mortbay.jetty.handler.DefaultHandler, which deals with unhandled requests in the server. If you have no webapps defined in the root context ("/"), visiting http://localhost:8080/ will 404, but will present a list of contexts that have been deployed on the server. DefaultHandler also serves up a Jetty favicon.
For more details about configuring static deployment, see WebAppDeployer.
Hot Deployment of Customized Contexts
In addition to deploying webapps at start-up, you can also do hot deployment: configure a context deployer which scans a specific directory for XML configuration files, and deploys/redeploys/undeploys a webapp if its configuration file has been modified, added, or removed. These configuration files also allow you to configure certain Jetty-specific per-context settings; configuration file and its format is specific to Jetty. To keep things short, I am not going to reproduce the entire configuration. Add this block to either of the previous examples:
<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>
That sets up a ContextDeployer, which will scan the $JETTY_HOME/contexts folder every 5 seconds for changes to the XML descriptors, and hot deploy as necessary. For more details, see ContextDeployer.
File Server, One Handler
Simple HTTP file server with one handler, similar to the embedded FileServer example and embedded OneHandler example. This example serves up purely static files from your current directory:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="Server" class="org.mortbay.jetty.Server">
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="ResourceHandler" class="org.mortbay.jetty.handler.ResourceHandler">
<Set name="resourceBase">.</Set>
</New>
</Set>
</Configure>
Note that ResourceHandler does not allow directory listing; if you visit a directory with no welcome files, you will get a 403 Forbidden error message. Try the exact path to the file.
If you just want a specific context to serve static content, while still serving dynamic web applications from other contexts, configure your server to allow hot deployment (see previous example), then set up a context to serve up Static Content.
File Server, Multiple Handlers
Simple HTTP file server with request logging. Similar to the embedded FileServer example and embedded ManyHandlers example
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="Server" class="org.mortbay.jetty.Server">
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.mortbay.jetty.Handler">
<Item>
<New id="ResourceHandler" class="org.mortbay.jetty.handler.ResourceHandler">
<Set name="resourceBase">./logs</Set>
</New>
</Item>
<Item>
<New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
<Set name="filename"><SystemProperty name="jetty.logs" default="./logs"/>/request.log</Set>
<Set name="append">false</Set>
</New>
</Set>
</Ref>
</Configure>
Similar to the one handler example, but defines multiple handlers. A handler can be configured either as soon as it is declared, or further down using the Ref tag. There is no difference in effect between the two. That example serves up static files in the logs directory under your current directory, and logs all requests since the server was last started to request.log.
To see this in action, go to http://localhost:8080/request.log and refresh a few times (you may need to hard refresh, to make sure you are not seeing a cached copy of the data).
For simplicity's sake, the logfile's name does not contain a date; see jetty.xml for an extended configuration which does.
Either a HandlerCollection or a HandlerList can be used when setting multiple handlers. org.mortbay.jetty.handler.HandlerCollection calls all handlers in turn. org.mortbay.jetty.handler.HandlerList calls each contained handler until either an exception is thrown, the response is committed,or a positive response status is sent. In this case, HandlerCollection was chosen so that the RequestLogHandler could log the requests.
参考资料:
http://docs.codehaus.org/display/JETTY/Newbie+Guide+to+Jetty