首页 > 代码库 > Jetty实战之 嵌入式运行Jetty 配置Https
Jetty实战之 嵌入式运行Jetty 配置Https
在开发Java web项目时候,可以在项目中嵌入Jetty服务的方式来运行web程序。
嵌入式Jetty服务比较简洁,不用在服务器再部署其他服务。
本人用的Jetty9.3,其他版本的应该也差不多,我见过别人的嵌入式Jetty服务,他们都是把一些配置参数写死在代码里,不利于维护,我是做了进一步的改进,把配置参数放在配置文件,然后直接把配置参数读到相应的类里。
首先列一下Jetty项目里比较重要的xml:jetty-https.xml,jetty-ssl.xml,jetty-ssl-context.xml,jetty.xml
jetty-https.xml
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"><!-- ============================================================= --><!-- Configure a HTTPS connector. --><!-- This configuration must be used in conjunction with jetty.xml --><!-- and jetty-ssl.xml. --><!-- ============================================================= --><Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector"> <Call name="addIfAbsentConnectionFactory"> <Arg> <New class="org.eclipse.jetty.server.SslConnectionFactory"> <Arg name="next">http/1.1</Arg> <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg> </New> </Arg> </Call> <Call name="addConnectionFactory"> <Arg> <New class="org.eclipse.jetty.server.HttpConnectionFactory"> <Arg name="config"><Ref refid="sslHttpConfig" /></Arg> <Arg name="compliance"> <Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf"> <Arg> <Property name="jetty.http.compliance" default="RFC7230"/> </Arg></Call></Arg> </New> </Arg> </Call> </Configure>
jetty-ssl.xml
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"><!-- ============================================================= --><!-- Base SSL configuration --><!-- This configuration needs to be used together with 1 or more --><!-- of jetty-https.xml or jetty-http2.xml --><!-- ============================================================= --><Configure id="Server" class="org.eclipse.jetty.server.Server"> <!-- =========================================================== --> <!-- Add a SSL Connector with no protocol factories --> <!-- =========================================================== --> <Call name="addConnector"> <Arg> <New id="sslConnector" class="org.eclipse.jetty.server.ServerConnector"> <Arg name="server"><Ref refid="Server" /></Arg> <Arg name="acceptors" type="int"><Property name="jetty.ssl.acceptors" deprecated="ssl.acceptors" default="-1"/></Arg> <Arg name="selectors" type="int"><Property name="jetty.ssl.selectors" deprecated="ssl.selectors" default="-1"/></Arg> <Arg name="factories"> <Array type="org.eclipse.jetty.server.ConnectionFactory"> <!-- uncomment to support proxy protocol <Item> <New class="org.eclipse.jetty.server.ProxyConnectionFactory"/> </Item>--> </Array> </Arg> <Set name="host"><Property name="jetty.ssl.host" deprecated="jetty.host" /></Set> <Set name="port"><Property name="jetty.ssl.port" deprecated="ssl.port" default="8443" /></Set> <Set name="idleTimeout"><Property name="jetty.ssl.idleTimeout" deprecated="ssl.timeout" default="30000"/></Set> <Set name="soLingerTime"><Property name="jetty.ssl.soLingerTime" deprecated="ssl.soLingerTime" default="-1"/></Set> <Set name="acceptorPriorityDelta"><Property name="jetty.ssl.acceptorPriorityDelta" deprecated="ssl.acceptorPriorityDelta" default="0"/></Set> <Set name="acceptQueueSize"><Property name="jetty.ssl.acceptQueueSize" deprecated="ssl.acceptQueueSize" default="0"/></Set> </New> </Arg> </Call> <!-- =========================================================== --> <!-- Create a TLS specific HttpConfiguration based on the --> <!-- common HttpConfiguration defined in jetty.xml --> <!-- Add a SecureRequestCustomizer to extract certificate and --> <!-- session information --> <!-- =========================================================== --> <New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration"> <Arg><Ref refid="httpConfig"/></Arg> <Call name="addCustomizer"> <Arg> <New class="org.eclipse.jetty.server.SecureRequestCustomizer"> <Arg name="sniHostCheck" type="boolean"><Property name="jetty.ssl.sniHostCheck" default="true"/></Arg> <Arg name="stsMaxAgeSeconds" type="int"><Property name="jetty.ssl.stsMaxAgeSeconds" default="-1"/></Arg> <Arg name="stsIncludeSubdomains" type="boolean"><Property name="jetty.ssl.stsIncludeSubdomains" default="false"/></Arg> </New> </Arg> </Call> </New></Configure>
jetty-ssl-context.xml
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"><!-- ============================================================= --><!-- SSL ContextFactory configuration --><!-- ============================================================= --><!-- To configure Includes / Excludes for Cipher Suites or Protocols see tweak-ssl.xml example at https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites--><Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory"> <Set name="KeyStorePath"><Property name="jetty.base" default="." />/<Property name="jetty.sslContext.keyStorePath" deprecated="jetty.keystore" default="etc/keystore"/></Set> <Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" deprecated="jetty.keystore.password" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set> <Set name="KeyStoreType"><Property name="jetty.sslContext.keyStoreType" default="JKS"/></Set> <Set name="KeyStoreProvider"><Property name="jetty.sslContext.keyStoreProvider"/></Set> <Set name="KeyManagerPassword"><Property name="jetty.sslContext.keyManagerPassword" deprecated="jetty.keymanager.password" default="OBF:1u2u1wml1z7s1z7a1wnl1u2g"/></Set> <Set name="TrustStorePath"><Property name="jetty.base" default="." />/<Property name="jetty.sslContext.trustStorePath" deprecated="jetty.truststore" default="etc/keystore"/></Set> <Set name="TrustStorePassword"><Property name="jetty.sslContext.trustStorePassword" deprecated="jetty.truststore.password"/></Set> <Set name="TrustStoreType"><Property name="jetty.sslContext.trustStoreType"/></Set> <Set name="TrustStoreProvider"><Property name="jetty.sslContext.trustStoreProvider"/></Set> <Set name="EndpointIdentificationAlgorithm"></Set> <Set name="NeedClientAuth"><Property name="jetty.sslContext.needClientAuth" deprecated="jetty.ssl.needClientAuth" default="false"/></Set> <Set name="WantClientAuth"><Property name="jetty.sslContext.wantClientAuth" deprecated="jetty.ssl.wantClientAuth" default="false"/></Set> <Set name="useCipherSuitesOrder"><Property name="jetty.sslContext.useCipherSuitesOrder" default="true"/></Set> <Set name="sslSessionCacheSize"><Property name="jetty.sslContext.sslSessionCacheSize" default="-1"/></Set> <Set name="sslSessionTimeout"><Property name="jetty.sslContext.sslSessionTimeout" default="-1"/></Set> <Set name="RenegotiationAllowed"><Property name="jetty.sslContext.renegotiationAllowed" default="true"/></Set> <Set name="RenegotiationLimit"><Property name="jetty.sslContext.renegotiationLimit" default="5"/></Set></Configure>
源包里这几个xml文件是分别独立的,在配置https的时候是需要我们把这三个xml融合到jetty.xml文件里面的,自己经历过各种尝试,分别读三个文件,但并没有什么乱用,各种失败,最后自己想想了,之前用的http就是放在jetty文件里的,要配置https那肯定也能放到jetty里面。
具体的步骤如下:
1、先把jetty-ssl.xml里面的<Call name="addConnector">节点添加到jetty.xml文件里。
2、在jetty.xml文件里刚才添加的<Call name="addConnector">节点下<Array type="org.eclipse.jetty.server.ConnectionFactory">添加jetty-https.xml文件下的<New class="org.eclipse.jetty.server.SslConnectionFactory">节点和
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
</New>
3、把jetty-ssl.xml下的<New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">节点和jetty-ssl-context.xml(需要注意的一点是:需要把Configure改成New)里面的整个节点。
配置已经修改完,然后具体的相关配置根据自己的需要进行相应配置,需要注意的是,jetty.xml文件的节点顺序,New节点相当于声明变量,需要放在最顶部,要不然编译会报错。
接下来就是读取jetty.xml和jetty-jmx.xml文件到server的代码
public class HttpsServer { private static final String[] CFG_FILES = {"jetty.xml", "jetty-jmx.xml"}; private Server server; public HttpsServer() { server = new Server(); } public void start() throws Exception { if (server.isRunning()) { return; } ClassLoader loader = HttpServer.class.getClassLoader(); for (String fileName : CFG_FILES) { InputStream stream = loader.getResourceAsStream(fileName); if (stream != null) { XmlConfiguration config = new XmlConfiguration(stream); stream.close(); config.configure(this.server); } } server.start(); } public int getPort() { return ((ServerConnector) server.getConnectors()[0]).getPort(); } public void stop() throws Exception { if (server != null) { server.stop(); } }}
搞定,再说一下配置Https可能遇到的问题:
1、keystore 这个需要在linux生成,网上有现成的命令,并且需要把这个文件的正确路径要填写到配置文件里
2、注意节点的次序
Jetty实战之 嵌入式运行Jetty 配置Https