首页 > 代码库 > 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>
View Code

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>
View Code

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>
View Code

源包里这几个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