如何通过 xml 配置在 SSL 模式下启用嵌入式 jetty 9?
How to enable embedded jetty 9 in SSL mode through xml configuration?
我使用了单个 jetty.xml 并在此处添加了我的上下文和 http 配置来处理我的请求。我遵循了这种方法,因为我之前使用的是旧的 jetty 6,然后升级到 9,他们在那里划分了文件,我对较新的 jetty 中提到的配置感到困惑。
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- =============================================================== -->
<!-- Documentation of this file format can be found at: -->
<!-- https://www.eclipse.org/jetty/documentation/current/ -->
<!-- -->
<!-- Additional configuration files are available in $JETTY_HOME/etc -->
<!-- and can be mixed in. See start.ini file for the default -->
<!-- configuration files. -->
<!-- -->
<!-- For a description of the configuration mechanism, see the -->
<!-- output of: -->
<!-- java -jar start.jar -? -->
<!-- =============================================================== -->
<!-- =============================================================== -->
<!-- Configure a Jetty Server instance with an ID "Server" -->
<!-- Other configuration files may also configure the "Server" -->
<!-- ID, in which case they are adding configuration to the same -->
<!-- instance. If other configuration have a different ID, they -->
<!-- will create and configure another instance of Jetty. -->
<!-- Consult the javadoc of o.e.j.server.Server for all -->
<!-- configuration that may be set here. -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<New id="threadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads" type="int"><Property name="jetty.threadPool.minThreads" deprecated="threads.min" default="10"/></Set>
<Set name="maxThreads" type="int"><Property name="jetty.threadPool.maxThreads" deprecated="threads.max" default="200"/></Set>
<Set name="reservedThreads" type="int"><Property name="jetty.threadPool.reservedThreads" default="-1"/></Set>
<Set name="idleTimeout" type="int"><Property name="jetty.threadPool.idleTimeout" deprecated="threads.timeout" default="60000"/></Set>
<Set name="detailedDump" type="boolean"><Property name="jetty.threadPool.detailedDump" default="false"/></Set>
</New>
<!-- =========================================================== -->
<!-- Add shared Scheduler instance -->
<!-- =========================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.util.thread.ScheduledExecutorScheduler">
<Arg name="name"><Property name="jetty.scheduler.name"/></Arg>
<Arg name="daemon" type="boolean"><Property name="jetty.scheduler.daemon" default="false" /></Arg>
<Arg name="threads" type="int"><Property name="jetty.scheduler.threads" default="-1" /></Arg>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<!-- <Item>-->
<!-- <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>-->
<!-- </Item>-->
<Item>
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<!-- ======================================================= -->
<!-- Configure a Context for CTS -->
<!-- ======================================================= -->
<New class="org.eclipse.jetty.servlet.ServletContextHandler">
<Arg>
<Ref id="Contexts"/>
</Arg>
<Arg>/cts</Arg>
<Set name="resourceBase">
<SystemProperty name="jetty.home" default="."/>/</Set>
<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler"/>
</Set>
<Call name="addServlet">
<Arg>com.documentum.cts.webservices.remote.TransformationServlet</Arg>
<Arg>/</Arg>
</Call>
</New>
<New class="org.eclipse.jetty.servlet.ServletContextHandler">
<Arg>
<Ref id="Contexts"/>
</Arg>
<Arg>/cts/resource</Arg>
<Set name="resourceBase">
<SystemProperty name="jetty.home" default="."/>/../resource/</Set>
<Call name="addServlet">
<Arg>com.documentum.cts.webservices.remote.FileProxyServlet</Arg>
<Arg>/</Arg>
</Call>
</New>
<!-- =========================================================== -->
<!-- Http Configuration. -->
<!-- This is a common configuration instance used by all -->
<!-- connectors that can carry HTTP semantics (HTTP, HTTPS, etc.)-->
<!-- It configures the non wire protocol aspects of the HTTP -->
<!-- semantic. -->
<!-- -->
<!-- This configuration is only defined here and is used by -->
<!-- reference from other XML files such as jetty-http.xml, -->
<!-- jetty-https.xml and other configuration files which -->
<!-- instantiate the connectors. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.server.HttpConfiguration -->
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>
<New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server">
<Ref refid="Server" />
</Arg>
<Set name="host">
<SystemProperty name="jetty.http.host"/>
</Set>
<Set name="port">
<Property name="jetty.http.port" deprecated="jetty.port" default="9096" />
</Set>
<Set name="idleTimeout">
<Property name="jetty.http.idleTimeout" deprecated="http.timeout" default="30000"/>
</Set>
<Get name="SelectorManager">
<Set name="connectTimeout"><Property name="jetty.http.connectTimeout" default="15000"/></Set>
</Get>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Set the default handler structure for the Server -->
<!-- A handler collection is used to pass received requests to -->
<!-- both the ContextHandlerCollection, which selects the next -->
<!-- handler by context path and virtual host, and the -->
<!-- DefaultHandler, which handles any requests not handled by -->
<!-- the context handlers. -->
<!-- Other handlers may be added to the "Handlers" collection, -->
<!-- for example the jetty-requestlog.xml file adds the -->
<!-- RequestLogHandler after the default handler -->
<!-- =========================================================== -->
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Set name="filename">
<SystemProperty name="jetty.logs" default="../logs"/>/ws.request_yyyy_mm_dd.log</Set>
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">true</Set>
<Set name="logCookies">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
<!-- =========================================================== -->
<!-- extra server options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown"><Property name="jetty.server.stopAtShutdown" default="true"/></Set>
<Set name="stopTimeout"><Property name="jetty.server.stopTimeout" default="5000"/></Set>
<Set name="dumpAfterStart"><Property name="jetty.server.dumpAfterStart" deprecated="jetty.dump.start" default="false"/></Set>
<Set name="dumpBeforeStop"><Property name="jetty.server.dumpBeforeStop" deprecated="jetty.dump.stop" default="false"/></Set>
</Configure>
已编写以下代码来调用此配置:
Server myServer;
File theConfigFile = new File( "C://jetty//etc//jetty.xml" );
XmlConfiguration theXmlConfiguration = new XmlConfiguration( theConfigFile.toURL() );
theXmlConfiguration.configure( myServer );
myServer.start();
我想坚持使用 xml 配置 jetty 的方法,并在 SSL 模式下启用 http。有可能实现这一目标吗?提供的任何帮助都将非常有用。
天哪,这里有很多话要说。
在 Whosebug 上将大量不同的问题集中到一个问题中可不是个好主意!
- 正确使用
<Ref>
。是 <Ref refid="otherid">
,不是 <Ref id="idtothisref">
- 不要使用
ServletContextHandler
或 WebAppContext
中的构造函数引用来绑定处理程序树中的位置或定义上下文路径。这些应该在 XML 中定义为在您想要它们的处理程序树的位置内。
- 不要重新定义
Scheduler
,按照你现在的方式,你将有 2 个调度程序!
- 不要删除
DefaultHandler
是 Jetty 的关键组件,如果删除它,很多东西都会损坏。
- 不要在 Jetty 9 上使用
RequestLogHandler
,它在 Jetty 8 中已被弃用,仅存在于 Jetty 9 中以防止破坏配置(你实际上没有一个功能齐全的 RequestLog
使用处理程序方法,使用服务器方法。
NCSARequestLog
也已弃用,不要使用它,请使用 CustomRequestLog
并指定特定的 RequestLog.Writer
。
- 您的
ServletContextHandler
定义声明了一个 resourceBase
,但随后在 /
的默认 servlet url 模式上添加了一个 servlet。这是一种相互矛盾的行为组合。
- 您在
/
的默认 servlet url 模式(根据规范也称为“默认”)上有一个 resourceBase
和一个 DefaultServlet
,
- 或者你有一个自定义的 servlet,它实现了
DefaultServlet
的所有必需功能,这样你就有了一个理智的 ServletContext
(这意味着很多,包括错误处理、错误调度、http 缓存响应、缺少资源、非路径资源请求、完整的 http 规范路径规范化规则等。这只是 DefaultServlet
为您提供的表面内容以及一长串其他 ServletContext 规范定义的必需功能)
/cts/resource
的上下文路径无效,无法使用。这种模式最好在现有上下文中使用 url-pattern
来完成。
- 上下文路径规则是:
- 必须以“/”开头。
- 不能包含另一个斜杠“/”或“”
- 必须符合URL路径编码规则。
您对 XmlConfiguration
class 的使用未使用属性功能,或 XmlConfiguration
class 中内置的 ID 映射,因此这意味着您在 XML 中对 <Property>
和 <SystemProperty>
以及 id="foo"
引用的所有用法均未扩展或有效。
要么正确使用 XmlConfiguration
,要么删除 XML.
中的所有 <Property>
和 <SystemProperty>
元素
这是什么意思...
<!-- in your XML -->
<Set name="maxThreads" type="int"><Property name="jetty.threadPool.maxThreads" deprecated="threads.max" default="200"/></Set>
<!-- should be -->
<Set name="maxThreads" type="int">200</Set>
但为什么要为了避免正确使用 XmlConfiguration
而走极端呢?
使用没有属性的 XmlConfiguration
与直接使用 embedded-jetty 没有什么不同,所以跳过 XML 直接使用 embedded-jetty(更简单)。
如果您想正确使用 XmlConfiguration
,请继续阅读。
首先,不要重做 Jetty 中已经存在的东西,使用它。这意味着采用现有的 XML、现有的默认属性,并正确使用 XmlConfiguration
。
在你的例子中 XML 唯一的“自定义”是你的 2 ServletContextHandlers
,它们可以很容易地成为他们自己的 XML 文件。
首先,让我们向您展示如何使用直接使用 jetty-home 和 jetty-base 来完成这 2 个自定义 XML,后者使用 XML 和带有 XmlConfiguration
的属性。
我假设您在某处的 JAR 中有 class 用于 com.documentum.cts.webservices.remote.TransformationServlet
和 com.documentum.cts.webservices.remote.FileProxyServlet
的文件(对于此演示,我们将其称为 app.jar
)。
所以跟着...
$ curl -O https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/9.4.44.v20210927/jetty-home-9.4.44.v20210927.tar.gz
$ tar -zxf jetty-home-9.4.44.v20210927.tar.gz
$ mkdir my-jetty-base
[my-jetty-base]$ java -jar ../jetty-home-9.4.44.v20210927/start.jar --add-to-start=http,https,deploy,ext
[my-jetty-base]$ cp $HOME/projects/documentum/context.xml webapps/
[my-jetty-base]$ cp $HOME/projects/documentum/target/app.jar lib/ext
[my-jetty-base]$ mkdir webapps/context
[my-jetty-base]$ mkdir ctx-file-resources
[my-jetty-base]$ tree -F
.
├── ctx-file-resources/
├── etc/
│ └── keystore
├── lib/
│ └── ext/
│ └── app.jar
├── start.ini
└── webapps/
└── context.xml
5 directories, 4 files
[my-jetty-base]$ cat webapps/context.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="custom-context" class="org.eclipse.jetty.servlet.ServletContextHandler">
<Set name="contextPath">/ctx</Set>
<Set name="resourceBase"><Property name="jetty.webapps"/>/context</Set>
<Call name="addServlet">
<Arg>com.custom.TranServlet</Arg>
<Arg>/*</Arg>
</Call>
<Call id="fileProxHolder" name="addServlet">
<Arg>com.custom.FileProxServlet</Arg>
<Arg>/resource/*</Arg>
<Call name="setInitParameter">
<Arg>resourcesPath</Arg>
<Arg><Property name="jetty.base"/>/ctx-file-resources</Arg>
</Call>
</Call>
</Configure>
现在如果我们启动这个服务器...
[]$ cd my-jetty-base
[my-jetty-base]$ java -jar ../jetty-home-9.4.44.v20210927/start.jar
2021-10-29 11:16:11.446:INFO::main: Logging initialized @407ms to org.eclipse.jetty.util.log.StdErrLog
2021-10-29 11:16:11.696:INFO:oejs.Server:main: jetty-9.4.44.v20210927; built: 2021-09-27T23:02:44.612Z; git: 8da83308eeca865e495e53ef315a249d63ba9332; jvm 11.0.12+7
2021-10-29 11:16:11.712:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///home/joakim/code/jetty/distros/bases/my-jetty-base/webapps/] at interval 1
2021-10-29 11:16:11.748:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@1500b2f3{/ctx,file:///home/joakim/code/jetty/distros/bases/my-jetty-base/webapps/context,AVAILABLE}
2021-10-29 11:16:11.767:INFO:oejs.AbstractConnector:main: Started ServerConnector@12ec64c4{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-10-29 11:16:11.796:INFO:oejus.SslContextFactory:main: x509=X509@4f704591(jetty,h=[jetty.eclipse.org],a=[],w=[]) for Server@3ddc6915[provider=null,keyStore=file:///home/joakim/code/jetty/distros/bases/my-jetty-base/etc/keystore,trustStore=file:///home/joakim/code/jetty/distros/bases/my-jetty-base/etc/keystore]
2021-10-29 11:16:11.796:INFO:oejus.SslContextFactory:main: x509=X509@704deff2(mykey,h=[jetty server],a=[],w=[]) for Server@3ddc6915[provider=null,keyStore=file:///home/joakim/code/jetty/distros/bases/my-jetty-base/etc/keystore,trustStore=file:///home/joakim/code/jetty/distros/bases/my-jetty-base/etc/keystore]
2021-10-29 11:16:11.872:INFO:oejs.AbstractConnector:main: Started ServerConnector@435f001f{SSL, (ssl, http/1.1)}{0.0.0.0:8443}
2021-10-29 11:16:11.873:INFO:oejs.Server:main: Started @834ms
好了,您已经具备了 ServletContextHandler
运行 所需的最低限度。
它可以仅在 1 个上下文中提供 http://localhost:8080/ctx/
和 http://localhost:8080/ctx/resource/
。
同时支持http和https。
没有webapp,没有war,等等
但如果您仍想完全在 XML 中自己完成此操作,请正确使用 XmlConfiguration
。
Eclipse Jetty Embedded Cookbook
中有一个这样的例子
参见:XmlServer
,注意
这链接到 jetty-9.4.x
分支版本,在它们自己的分支上也有 jetty-10.0.x
和 jetty-11.0.x
版本。
重要说明:Jetty 9.4.x 处于维护模式并且正在逐渐关闭,只有错误修复和安全补丁会进入该主要版本。
Eclipse Jetty 上的主线稳定分支是当前的 Jetty 10.0.x 和 11.0.x,将它们用于新开发。
要正确使用 XmlConfiguration
,您必须是单独的 XML、属性和 ID 映射的war。
XmlConfiguration
的正常执行循环如下...
/**
* Configure for the list of XML Resources and Properties.
*
* @param xmls the xml resources (in order of execution)
* @param properties the properties to use with the XML
* @return the ID Map of configured objects (key is the id name in the XML, and the value is configured object)
* @throws Exception if unable to create objects or read XML
*/
public static Map<String, Object> configure(List<Resource> xmls, Map<String, String> properties) throws Exception
{
Map<String, Object> idMap = new HashMap<>();
// Configure everything
for (Resource xmlResource : xmls)
{
XmlConfiguration configuration = new XmlConfiguration(xmlResource);
configuration.getIdMap().putAll(idMap);
configuration.getProperties().putAll(properties);
configuration.configure();
idMap.putAll(configuration.getIdMap());
}
return idMap;
}
这需要一个 XML 的列表(按照正确的执行顺序)和一个属性映射。
XML 按顺序加载,您会返回 <id-string>
到 <configured-object>
的映射。
上面链接的示例有一个完整的示例,XML 来自 jetty-home(未修改),一些自定义 XML 包含新功能。
它甚至包括 SSL / HTTPS 层并展示了如何配置它(通过属性)。
它显示了如何设置 XML 列表和属性。
以及如何从 ID 映射中获取服务器。
为了获得最佳成功,请将 jetty-home 中的 XML 视为只读,不要修改它,不要编辑它,你不需要。
老实说,不要更改 XML,您不必这样做。在 Jetty 9.4 的 200 多万次安装中,没有一个经过验证的案例
需要从 jetty-home change/edit XML(人们认为他们需要,但这只是因为他们不明白如何
正确使用 Jetty XML 或 XmlConfiguration
,并且将每个示例提供给我们作为他们需要编辑 XML 的“证明”
在您不需要的地方经常以多种方式显示)。
我们非常相信这一点,jetty-home 中的 XML 现在是只读的!
我使用了单个 jetty.xml 并在此处添加了我的上下文和 http 配置来处理我的请求。我遵循了这种方法,因为我之前使用的是旧的 jetty 6,然后升级到 9,他们在那里划分了文件,我对较新的 jetty 中提到的配置感到困惑。
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- =============================================================== -->
<!-- Documentation of this file format can be found at: -->
<!-- https://www.eclipse.org/jetty/documentation/current/ -->
<!-- -->
<!-- Additional configuration files are available in $JETTY_HOME/etc -->
<!-- and can be mixed in. See start.ini file for the default -->
<!-- configuration files. -->
<!-- -->
<!-- For a description of the configuration mechanism, see the -->
<!-- output of: -->
<!-- java -jar start.jar -? -->
<!-- =============================================================== -->
<!-- =============================================================== -->
<!-- Configure a Jetty Server instance with an ID "Server" -->
<!-- Other configuration files may also configure the "Server" -->
<!-- ID, in which case they are adding configuration to the same -->
<!-- instance. If other configuration have a different ID, they -->
<!-- will create and configure another instance of Jetty. -->
<!-- Consult the javadoc of o.e.j.server.Server for all -->
<!-- configuration that may be set here. -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<New id="threadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads" type="int"><Property name="jetty.threadPool.minThreads" deprecated="threads.min" default="10"/></Set>
<Set name="maxThreads" type="int"><Property name="jetty.threadPool.maxThreads" deprecated="threads.max" default="200"/></Set>
<Set name="reservedThreads" type="int"><Property name="jetty.threadPool.reservedThreads" default="-1"/></Set>
<Set name="idleTimeout" type="int"><Property name="jetty.threadPool.idleTimeout" deprecated="threads.timeout" default="60000"/></Set>
<Set name="detailedDump" type="boolean"><Property name="jetty.threadPool.detailedDump" default="false"/></Set>
</New>
<!-- =========================================================== -->
<!-- Add shared Scheduler instance -->
<!-- =========================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.util.thread.ScheduledExecutorScheduler">
<Arg name="name"><Property name="jetty.scheduler.name"/></Arg>
<Arg name="daemon" type="boolean"><Property name="jetty.scheduler.daemon" default="false" /></Arg>
<Arg name="threads" type="int"><Property name="jetty.scheduler.threads" default="-1" /></Arg>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<!-- <Item>-->
<!-- <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>-->
<!-- </Item>-->
<Item>
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<!-- ======================================================= -->
<!-- Configure a Context for CTS -->
<!-- ======================================================= -->
<New class="org.eclipse.jetty.servlet.ServletContextHandler">
<Arg>
<Ref id="Contexts"/>
</Arg>
<Arg>/cts</Arg>
<Set name="resourceBase">
<SystemProperty name="jetty.home" default="."/>/</Set>
<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler"/>
</Set>
<Call name="addServlet">
<Arg>com.documentum.cts.webservices.remote.TransformationServlet</Arg>
<Arg>/</Arg>
</Call>
</New>
<New class="org.eclipse.jetty.servlet.ServletContextHandler">
<Arg>
<Ref id="Contexts"/>
</Arg>
<Arg>/cts/resource</Arg>
<Set name="resourceBase">
<SystemProperty name="jetty.home" default="."/>/../resource/</Set>
<Call name="addServlet">
<Arg>com.documentum.cts.webservices.remote.FileProxyServlet</Arg>
<Arg>/</Arg>
</Call>
</New>
<!-- =========================================================== -->
<!-- Http Configuration. -->
<!-- This is a common configuration instance used by all -->
<!-- connectors that can carry HTTP semantics (HTTP, HTTPS, etc.)-->
<!-- It configures the non wire protocol aspects of the HTTP -->
<!-- semantic. -->
<!-- -->
<!-- This configuration is only defined here and is used by -->
<!-- reference from other XML files such as jetty-http.xml, -->
<!-- jetty-https.xml and other configuration files which -->
<!-- instantiate the connectors. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.server.HttpConfiguration -->
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>
<New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server">
<Ref refid="Server" />
</Arg>
<Set name="host">
<SystemProperty name="jetty.http.host"/>
</Set>
<Set name="port">
<Property name="jetty.http.port" deprecated="jetty.port" default="9096" />
</Set>
<Set name="idleTimeout">
<Property name="jetty.http.idleTimeout" deprecated="http.timeout" default="30000"/>
</Set>
<Get name="SelectorManager">
<Set name="connectTimeout"><Property name="jetty.http.connectTimeout" default="15000"/></Set>
</Get>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Set the default handler structure for the Server -->
<!-- A handler collection is used to pass received requests to -->
<!-- both the ContextHandlerCollection, which selects the next -->
<!-- handler by context path and virtual host, and the -->
<!-- DefaultHandler, which handles any requests not handled by -->
<!-- the context handlers. -->
<!-- Other handlers may be added to the "Handlers" collection, -->
<!-- for example the jetty-requestlog.xml file adds the -->
<!-- RequestLogHandler after the default handler -->
<!-- =========================================================== -->
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Set name="filename">
<SystemProperty name="jetty.logs" default="../logs"/>/ws.request_yyyy_mm_dd.log</Set>
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">true</Set>
<Set name="logCookies">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
<!-- =========================================================== -->
<!-- extra server options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown"><Property name="jetty.server.stopAtShutdown" default="true"/></Set>
<Set name="stopTimeout"><Property name="jetty.server.stopTimeout" default="5000"/></Set>
<Set name="dumpAfterStart"><Property name="jetty.server.dumpAfterStart" deprecated="jetty.dump.start" default="false"/></Set>
<Set name="dumpBeforeStop"><Property name="jetty.server.dumpBeforeStop" deprecated="jetty.dump.stop" default="false"/></Set>
</Configure>
已编写以下代码来调用此配置:
Server myServer;
File theConfigFile = new File( "C://jetty//etc//jetty.xml" );
XmlConfiguration theXmlConfiguration = new XmlConfiguration( theConfigFile.toURL() );
theXmlConfiguration.configure( myServer );
myServer.start();
我想坚持使用 xml 配置 jetty 的方法,并在 SSL 模式下启用 http。有可能实现这一目标吗?提供的任何帮助都将非常有用。
天哪,这里有很多话要说。
在 Whosebug 上将大量不同的问题集中到一个问题中可不是个好主意!
- 正确使用
<Ref>
。是<Ref refid="otherid">
,不是<Ref id="idtothisref">
- 不要使用
ServletContextHandler
或WebAppContext
中的构造函数引用来绑定处理程序树中的位置或定义上下文路径。这些应该在 XML 中定义为在您想要它们的处理程序树的位置内。 - 不要重新定义
Scheduler
,按照你现在的方式,你将有 2 个调度程序! - 不要删除
DefaultHandler
是 Jetty 的关键组件,如果删除它,很多东西都会损坏。 - 不要在 Jetty 9 上使用
RequestLogHandler
,它在 Jetty 8 中已被弃用,仅存在于 Jetty 9 中以防止破坏配置(你实际上没有一个功能齐全的RequestLog
使用处理程序方法,使用服务器方法。 NCSARequestLog
也已弃用,不要使用它,请使用CustomRequestLog
并指定特定的RequestLog.Writer
。- 您的
ServletContextHandler
定义声明了一个resourceBase
,但随后在/
的默认 servlet url 模式上添加了一个 servlet。这是一种相互矛盾的行为组合。- 您在
/
的默认 servlet url 模式(根据规范也称为“默认”)上有一个resourceBase
和一个DefaultServlet
, - 或者你有一个自定义的 servlet,它实现了
DefaultServlet
的所有必需功能,这样你就有了一个理智的ServletContext
(这意味着很多,包括错误处理、错误调度、http 缓存响应、缺少资源、非路径资源请求、完整的 http 规范路径规范化规则等。这只是DefaultServlet
为您提供的表面内容以及一长串其他 ServletContext 规范定义的必需功能)
- 您在
/cts/resource
的上下文路径无效,无法使用。这种模式最好在现有上下文中使用url-pattern
来完成。- 上下文路径规则是:
- 必须以“/”开头。
- 不能包含另一个斜杠“/”或“”
- 必须符合URL路径编码规则。
- 上下文路径规则是:
您对 XmlConfiguration
class 的使用未使用属性功能,或 XmlConfiguration
class 中内置的 ID 映射,因此这意味着您在 XML 中对 <Property>
和 <SystemProperty>
以及 id="foo"
引用的所有用法均未扩展或有效。
要么正确使用 XmlConfiguration
,要么删除 XML.
<Property>
和 <SystemProperty>
元素
这是什么意思...
<!-- in your XML -->
<Set name="maxThreads" type="int"><Property name="jetty.threadPool.maxThreads" deprecated="threads.max" default="200"/></Set>
<!-- should be -->
<Set name="maxThreads" type="int">200</Set>
但为什么要为了避免正确使用 XmlConfiguration
而走极端呢?
使用没有属性的 XmlConfiguration
与直接使用 embedded-jetty 没有什么不同,所以跳过 XML 直接使用 embedded-jetty(更简单)。
如果您想正确使用 XmlConfiguration
,请继续阅读。
首先,不要重做 Jetty 中已经存在的东西,使用它。这意味着采用现有的 XML、现有的默认属性,并正确使用 XmlConfiguration
。
在你的例子中 XML 唯一的“自定义”是你的 2 ServletContextHandlers
,它们可以很容易地成为他们自己的 XML 文件。
首先,让我们向您展示如何使用直接使用 jetty-home 和 jetty-base 来完成这 2 个自定义 XML,后者使用 XML 和带有 XmlConfiguration
的属性。
我假设您在某处的 JAR 中有 class 用于 com.documentum.cts.webservices.remote.TransformationServlet
和 com.documentum.cts.webservices.remote.FileProxyServlet
的文件(对于此演示,我们将其称为 app.jar
)。
所以跟着...
$ curl -O https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/9.4.44.v20210927/jetty-home-9.4.44.v20210927.tar.gz
$ tar -zxf jetty-home-9.4.44.v20210927.tar.gz
$ mkdir my-jetty-base
[my-jetty-base]$ java -jar ../jetty-home-9.4.44.v20210927/start.jar --add-to-start=http,https,deploy,ext
[my-jetty-base]$ cp $HOME/projects/documentum/context.xml webapps/
[my-jetty-base]$ cp $HOME/projects/documentum/target/app.jar lib/ext
[my-jetty-base]$ mkdir webapps/context
[my-jetty-base]$ mkdir ctx-file-resources
[my-jetty-base]$ tree -F
.
├── ctx-file-resources/
├── etc/
│ └── keystore
├── lib/
│ └── ext/
│ └── app.jar
├── start.ini
└── webapps/
└── context.xml
5 directories, 4 files
[my-jetty-base]$ cat webapps/context.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="custom-context" class="org.eclipse.jetty.servlet.ServletContextHandler">
<Set name="contextPath">/ctx</Set>
<Set name="resourceBase"><Property name="jetty.webapps"/>/context</Set>
<Call name="addServlet">
<Arg>com.custom.TranServlet</Arg>
<Arg>/*</Arg>
</Call>
<Call id="fileProxHolder" name="addServlet">
<Arg>com.custom.FileProxServlet</Arg>
<Arg>/resource/*</Arg>
<Call name="setInitParameter">
<Arg>resourcesPath</Arg>
<Arg><Property name="jetty.base"/>/ctx-file-resources</Arg>
</Call>
</Call>
</Configure>
现在如果我们启动这个服务器...
[]$ cd my-jetty-base
[my-jetty-base]$ java -jar ../jetty-home-9.4.44.v20210927/start.jar
2021-10-29 11:16:11.446:INFO::main: Logging initialized @407ms to org.eclipse.jetty.util.log.StdErrLog
2021-10-29 11:16:11.696:INFO:oejs.Server:main: jetty-9.4.44.v20210927; built: 2021-09-27T23:02:44.612Z; git: 8da83308eeca865e495e53ef315a249d63ba9332; jvm 11.0.12+7
2021-10-29 11:16:11.712:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///home/joakim/code/jetty/distros/bases/my-jetty-base/webapps/] at interval 1
2021-10-29 11:16:11.748:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@1500b2f3{/ctx,file:///home/joakim/code/jetty/distros/bases/my-jetty-base/webapps/context,AVAILABLE}
2021-10-29 11:16:11.767:INFO:oejs.AbstractConnector:main: Started ServerConnector@12ec64c4{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-10-29 11:16:11.796:INFO:oejus.SslContextFactory:main: x509=X509@4f704591(jetty,h=[jetty.eclipse.org],a=[],w=[]) for Server@3ddc6915[provider=null,keyStore=file:///home/joakim/code/jetty/distros/bases/my-jetty-base/etc/keystore,trustStore=file:///home/joakim/code/jetty/distros/bases/my-jetty-base/etc/keystore]
2021-10-29 11:16:11.796:INFO:oejus.SslContextFactory:main: x509=X509@704deff2(mykey,h=[jetty server],a=[],w=[]) for Server@3ddc6915[provider=null,keyStore=file:///home/joakim/code/jetty/distros/bases/my-jetty-base/etc/keystore,trustStore=file:///home/joakim/code/jetty/distros/bases/my-jetty-base/etc/keystore]
2021-10-29 11:16:11.872:INFO:oejs.AbstractConnector:main: Started ServerConnector@435f001f{SSL, (ssl, http/1.1)}{0.0.0.0:8443}
2021-10-29 11:16:11.873:INFO:oejs.Server:main: Started @834ms
好了,您已经具备了 ServletContextHandler
运行 所需的最低限度。
它可以仅在 1 个上下文中提供 http://localhost:8080/ctx/
和 http://localhost:8080/ctx/resource/
。
同时支持http和https。
没有webapp,没有war,等等
但如果您仍想完全在 XML 中自己完成此操作,请正确使用 XmlConfiguration
。
Eclipse Jetty Embedded Cookbook
中有一个这样的例子参见:XmlServer
,注意
这链接到 jetty-9.4.x
分支版本,在它们自己的分支上也有 jetty-10.0.x
和 jetty-11.0.x
版本。
重要说明:Jetty 9.4.x 处于维护模式并且正在逐渐关闭,只有错误修复和安全补丁会进入该主要版本。
Eclipse Jetty 上的主线稳定分支是当前的 Jetty 10.0.x 和 11.0.x,将它们用于新开发。
要正确使用 XmlConfiguration
,您必须是单独的 XML、属性和 ID 映射的war。
XmlConfiguration
的正常执行循环如下...
/**
* Configure for the list of XML Resources and Properties.
*
* @param xmls the xml resources (in order of execution)
* @param properties the properties to use with the XML
* @return the ID Map of configured objects (key is the id name in the XML, and the value is configured object)
* @throws Exception if unable to create objects or read XML
*/
public static Map<String, Object> configure(List<Resource> xmls, Map<String, String> properties) throws Exception
{
Map<String, Object> idMap = new HashMap<>();
// Configure everything
for (Resource xmlResource : xmls)
{
XmlConfiguration configuration = new XmlConfiguration(xmlResource);
configuration.getIdMap().putAll(idMap);
configuration.getProperties().putAll(properties);
configuration.configure();
idMap.putAll(configuration.getIdMap());
}
return idMap;
}
这需要一个 XML 的列表(按照正确的执行顺序)和一个属性映射。
XML 按顺序加载,您会返回 <id-string>
到 <configured-object>
的映射。
上面链接的示例有一个完整的示例,XML 来自 jetty-home(未修改),一些自定义 XML 包含新功能。 它甚至包括 SSL / HTTPS 层并展示了如何配置它(通过属性)。 它显示了如何设置 XML 列表和属性。 以及如何从 ID 映射中获取服务器。
为了获得最佳成功,请将 jetty-home 中的 XML 视为只读,不要修改它,不要编辑它,你不需要。
老实说,不要更改 XML,您不必这样做。在 Jetty 9.4 的 200 多万次安装中,没有一个经过验证的案例
需要从 jetty-home change/edit XML(人们认为他们需要,但这只是因为他们不明白如何
正确使用 Jetty XML 或 XmlConfiguration
,并且将每个示例提供给我们作为他们需要编辑 XML 的“证明”
在您不需要的地方经常以多种方式显示)。
我们非常相信这一点,jetty-home 中的 XML 现在是只读的!