Jetty使用教程(一)——開始使用Jetty


一、Jetty簡介

1.1 什么是Jetty

  Jetty是一個提供HHTP服務器、HTTP客戶端和javax.servlet容器的開源項目。
 
  這個入門教程分為五個部分:
  • 第一部分部分重點介紹如何使用Jetty,它提供如下信息,如什么是Jetty,從哪可以下載它,怎么在像Maven一樣的倉庫中找到它。這一部分同樣會提供啟動Jetty和如何配置Jetty的快速入門。
  • 第二部分從更細致的方面介紹Jetty的配置,介紹怎么用Jetty來部署一個web應用程序,怎么配置容器和連接,以及如何實現SSL和其它安全措施。
  • Jetty的管理員應該關注第三部分。從啟動Jetty容器開始到session管理,日志記錄,HTTP/2支持和Jetty優化,這一章節將幫助Jetty管理員獲得更多關於Jetty服務以外的知識,這一章節同樣包含容器最常用的特性配置如JNDI和JMX。
  • 針對使用Jetty的高級用戶,第四部分着重於Jetty的開發,本章節的重點是如何將Jetty嵌入一個已經存在的應用程序中。這部分包含幾個簡單的例子和操作Jetty框架的指南。這一部分同樣包含如何使用Jetty的maven插件以及Jetty調試。
  • 最后一個部分是引用部分,也包含Jetty的架構信息,Jetty的XML語法介紹,以及常見問題的解析,這章也介紹如何參與Jetty社區,如何貢獻代碼,以及如何尋求幫助。

1.2 如何選擇Jetty的版本

  Jetty9是Jetty的最近一個版本且比之前的版本有很大的改進,其中一個改進是Jetty所有特性已經體現在Jetty9的文檔里。所以對於很多使用Jetty老版本的用戶,我們建議使用Jetty9,我們也表示將會在接下來的幾年里積極維護這一個版本。
 
表格1.1Jetty版本
版本 Year Home JVM 協議 Servlet JSP 狀態

9.3

2015

Eclipse

1.8

HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), 

WebSocket (RFC 6455, JSR 356), FastCGI

3.1

2.3

穩定版本

9.2

2014

Eclipse

1.7

HTTP/1.1 RFC2616, javax.websocket, SPDY v3

3.1

2.3

穩定版本

8

2009-

Eclipse/Codehaus

1.6

HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3

3.0

2.2

珍貴版本

7

2008-

Eclipse/Codehaus

1.5

HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3

2.5

2.1

珍貴版本

6

2006-2010

Codehaus

1.4-1.5

HTTP/1.1 RFC2616

2.5

2.0

已經作廢

5

2003-2009

Sourceforge

1.2-1.5

HTTP/1.1 RFC2616

2.4

2.0

已經作廢

4

2001-2006

Sourceforge

1.2, J2ME

HTTP/1.1 RFC2616

2.3

1.2

遠古時期

3

1999-2002

Sourceforge

1.2

HTTP/1.1 RFC2068

2.2

1.1

石器時代

2

1998-2000

Mortbay

1.1

HTTP/1.0 RFC1945

2.1

1.0

傳說級別

1

1995-1998

Mortbay

1.0

HTTP/1.0 RFC1945

-

-

神話級別

1.3 Jetty 和Java EE Web規范

  Jetty實現的Java EE規范主要是Servlet規范,最新的Java EE平台介紹了一個新的Web 規范,建議開發者只需要大部分技術中的一部分即可。然而Jetty沒有實現Web 規范中所有的技術,Jetty設計為一個容器,可以使用插件自由擴展想要的功能。

1.3.1 Java EE 7 Web規范

  在Java EE7的規范中,更新了一些重要的功能以及添加了一些新的:
 
表格1.2 JavaEE7 Web Profile
JSR 名稱 jetty-9.1.x是否包含 支持插件

JSR 340

Servlet Specification API 3.1

Yes

 

JSR 344

Java Server Faces 2.2 (JSF)

No

Yes, Mojarra or MyFaces

JSR 245 / JSR 341

Java Server Pages 2.3/Java Expression Language 3.0 (JSP/EL)

Yes

Yes

JSR 52

Java Standard Tag Library 1.2 (JSTL)

Yes

Yes

JSR 45

Debugging Support for Other Languages 1.0

Yes (via JSP)

Yes (via JSP)

JSR 346

Contexts and Dependency Injection for the 

JavaEE Platform 1.1 (Web Beans)

No

Yes, Weld

JSR 330

Dependency Injection for Java 1.0

No

Yes as part of a CDI implementation, Weld

JSR 316

Managed Beans 1.0

No

Yes, as part of another technology

JSR 345

Enterprise JavaBeans 3.2 Lite

No

 

JSR 338

Java Persistance 2.1 (JPA)

No

Yes, eg Hibernate

JSR 250

Common Annotations for the Java Platform 1.2

Yes

Partially (for non-core Servlet Spec annotations)

JSR 907

Java Transaction API 1.2 (JTA)

Yes

Yes

JSR 349

Bean Validation 1.1

No

Yes as part of another technology eg JSF, or 

a stand-alone implementation such as Hiberate Validator

JSR 339

Java API for RESTful Web Services 2.0 (JAX-RS)

No

 

JSR 356

Java API for Websocket 1.0

Yes

No

JSR 353

Java API for JSON Processing 1.0 (JSON-P)

No

Yes, eg JSON-P reference implementation

JSR 318

Interceptors 1.2

No

Yes as part of a CDI implementation


1.3.2 Jetty EE 6 Web Profile

  下面介紹JavaEE6 Web Profile,以及與Jetty的關系

表格 1.3. Java EE 6 Web Profile

JSR Name Included with jetty-9.0.x Pluggable

JSR 315

Servlet Specification API 3.0

Yes

 

JSR 314

JavaServer Faces 2.0 (JSF)

No

Yes, for example, Mojarra or MyFaces

JSR 245

JavaServer Pages 2.2/Java Expression

Language 2.2 (JSP/EL)

Yes

Yes

JSR 52

Java Standard Tag Library 1.2 (JSTL)

Yes

Yes

JSR 45

Debugging Support for Other Languages 1.0

Yes (via JSP)

Yes (via JSP)

JSR 299

Contexts and Dependency Injection for

the Java EE Platform 1.0 (Web Beans)

No

Yes, Weld or OpenWebBeans

JSR 330

Dependency Injection for Java 1.0

No

Yes as part of a CDI implementation, Weld

JSR 316

Managed Beans 1.0

No

Yes, as part of another technology.

JSR 318

Enterprise JavaBeans 3.1

No

Yes, OpenEJB

JSR 317

Java Persistance 2.0 (JPA)

No

Yes, Hibernate

JSR 250

Common Annotations for the Java Platform

Yes

Partially (for non-core Servlet Spec annotations)

JSR 907

Java Transaction API (JTA)

Yes

Implementations are pluggable, such as Atomikos, JOTM, 

Jencks (Geronimo Transaction Manager)

JSR 303

Bean Validation 1.0

No

Yes as part of another technology (JSF), or a stand-alone 

implementation such as Hiberate Validator

1.4 在Maven中獲取Jetty

1.4.1 Maven坐標

  Jetty從一開始就已經存在於Maven中心了,所以Maven的坐標在最近幾年也發生了變化,當Jetty基於SourceForge管理時Maven的groupId是org.mortbay.jetty,當Jetty 7來到eclipse后groupId也改變了。
Jetty的POM坐標如下
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-project</artifactId>
  <version>${project.version}</version>
</dependency>

 1.4.2 在Maven中心的更新日志

  Jetty不同版本的更新日志記錄在一個叫做VERSIONS.txt的文件中,也可以在Maven中心找到,坐標如下
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-project</artifactId>
  <version>${project.version}</version>
  <classifier>version</classifier>
  <type>txt</type>
</dependency>

 二、Jetty的使用

  你可以通過多種方式將Jetty植入使用的程序中,在不同的系統中使用它,或者做為一個獨立的服務器來使用,這一節介紹了后者,即作為一個單獨的服務器來部署web應用。

2.1 下載Jetty

2.1.1 下載Jetty項目

  Jetty的下載網頁為:https://www.eclipse.org/jetty/download.html
  如果jdk環境支持盡量使用最新版本,將下載后的解壓放在使用的位置,以后章節將使用JETTY_HOME或者 $(jetty.home)來代表Jetty的存放路徑。

2.1.2 Jetty工程簡介

  Jetty所有頂級目錄簡介:

表格 2.1. Contents

Location Description

license-eplv10-aslv20.html

Jetty的許可文件

README.txt

有用的開始信息

VERSION.txt

版本信息

bin/

存放在Unix系統下運行的shell腳本

demo-base/

一個可運行包含示例web應用的Jetty服務器基目錄

etc/

Jetty的配置文件

lib/

Jetty運行所必須的jar文件

logs/

日志

modules/

各個模塊

notice.html

許可信息等

resources/

包含新增到classpath配置文件夾,如log4j.properties

start.ini

存放啟動信息

start.jar

運行Jetty的jar

webapps/

一個用來存放運行在默認配置下的Jetty Web應用目錄

2.2 運行Jetty

  執行以下代碼,Jetty會在默認8080端口運行
cd $JETTY_HOME
java -jar start.jar

   若執行成功會輸出以下信息

2015-06-04 10:50:44.806:INFO::main: Logging initialized @334ms
2015-06-04 10:50:44.858:WARN:oejs.HomeBaseWarning:main: This instance of Jetty is not running from a separate {jetty.base} directory, this is not recommended. See documentation at http://www.eclipse.org/jetty/documentation/current/startup.html
2015-06-04 10:50:44.995:INFO:oejs.Server:main: jetty-9.3.0.v20150601
2015-06-04 10:50:45.012:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///opt/jetty-distribution-9.3.0.v20150601/webapps/] at interval 1
2015-06-04 10:50:45.030:INFO:oejs.ServerConnector:main: Started ServerConnector@19dfb72a{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2015-06-04 10:50:45.030:INFO:oejs.Server:main: Started @558ms

  你可以通過瀏覽器訪問http://localhost:8080.。然而在$JETTY_HOME/webapps目錄下並沒有部署任何web應用,所以你將會看到一個Jetty提供的404錯誤頁面,並不推薦在$JETTY_HOME下運行Jetty,而是建議運行一個Jetty基礎應用。錯誤頁面如下

2.2.1 基礎應用例子

  標准的Jetty應用,有一個demo-base的文件夾,可以不在$JETTY_HOME下運行Jetty,在demo-base文件夾下執行以下命令:
> cd $JETTY_HOME/demo-base/
> java -jar $JETTY_HOME/start.jar

  成功運行將有如下信息輸出:

2015-06-04 10:55:24.161:INFO::main: Logging initialized @308ms
2015-06-04 10:55:24.431:WARN::main: demo test-realm is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 10:55:24.434:INFO:oejs.Server:main: jetty-9.3.0.v20150601
2015-06-04 10:55:24.457:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///opt/jetty-distribution-9.3.0.v20150601/demo-base/webapps/] at interval 1
2015-06-04 10:55:24.826:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@c038203{/,file:///opt/jetty-distribution-9.3.0.v20150601/demo-base/webapps/ROOT/,AVAILABLE}{/ROOT}
2015-06-04 10:55:24.929:WARN::main: test-jaas webapp is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 10:55:24.978:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@46238e3f{/test-jaas,file:///tmp/jetty-0.0.0.0-8080-test-jaas.war-_test-jaas-any-9105214562680121772.dir/webapp/,AVAILABLE}{/test-jaas.war}
2015-06-04 10:55:25.162:WARN::main: async-rest webapp is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 10:55:25.208:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@6b67034{/async-rest,[file:///tmp/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-1023939491558622183.dir/webapp/, jar:file:///tmp/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-1023939491558622183.dir/webapp/WEB-INF/lib/example-async-rest-jar-9.3.0.v20150601.jar!/META-INF/resources],AVAILABLE}{/async-rest.war}
2015-06-04 10:55:25.311:WARN::main: test-jndi webapp is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 10:55:25.386:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@8b96fde{/test-jndi,file:///tmp/jetty-0.0.0.0-8080-test-jndi.war-_test-jndi-any-1692053319754270133.dir/webapp/,AVAILABLE}{/test-jndi.war}
2015-06-04 10:55:25.508:WARN::main: test-spec webapp is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 10:55:25.594:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@69930714{/test-spec,[file:///tmp/jetty-0.0.0.0-8080-test-spec.war-_test-spec-any-5518740932795802823.dir/webapp/, jar:file:///tmp/jetty-0.0.0.0-8080-test-spec.war-_test-spec-any-5518740932795802823.dir/webapp/WEB-INF/lib/test-web-fragment-9.3.0.v20150601.jar!/META-INF/resources],AVAILABLE}{/test-spec.war}
2015-06-04 10:55:25.781:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@3eb7fc54{/proxy,file:///tmp/jetty-0.0.0.0-8080-xref-proxy.war-_xref-proxy-any-3068657547009829038.dir/webapp/,AVAILABLE}{/xref-proxy.war}
2015-06-04 10:55:25.786:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.MovedContextHandler@59662a0b{/oldContextPath,null,AVAILABLE}
2015-06-04 10:55:25.951:WARN::main: test webapp is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 10:55:26.248:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@4f83df68{/test,file:///tmp/jetty-0.0.0.0-8080-test.war-_test-any-5238659347611323540.dir/webapp/,AVAILABLE}{/test.war}
2015-06-04 10:55:26.255:INFO:oejs.ServerConnector:main: Started ServerConnector@5a9c4ad9{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2015-06-04 10:55:26.259:INFO:oejus.SslContextFactory:main: x509={jetty.eclipse.org=jetty} wild={} alias=null for SslContextFactory@23941fb4(file:///opt/jetty-distribution-9.3.0.v20150601/demo-base/etc/keystore,file:///opt/jetty-distribution-9.3.0.v20150601/demo-base/etc/keystore)
2015-06-04 10:55:26.269:INFO:oejs.ServerConnector:main: Started ServerConnector@5d908d47{SSL,[ssl, http/1.1]}{0.0.0.0:8443}
2015-06-04 10:55:26.270:INFO:oejs.Server:main: Started @2417ms

  現在可以通過瀏覽器訪問 http://localhost:8080,  此時可以看到一個Jetty的歡迎頁面,頁面上包含幾個簡單的例子,歡迎頁面如下

警告

示例的web應用程序不一定是絕對安全的,所以不應該部署在生產環境上。

  你可以通過以下命令查看示例應用的配置信息 

> cd $JETTY_HOME/demo-base/
> java -jar $JETTY_HOME/start.jar --list-modules
...
 
> java -jar %JETTY_HOME/start.jar --list-config
...

--list-modules:此命令將返回當前服務所有可用的模塊,同時也會顯示本地的模塊,信息包括模塊實現的順序,依賴模塊以及相應的jar信息

--list-config:顯示運行環境和配置文件等信息 

2.2.2 創建一個新的Jetty基目錄

  demo-base目錄是jetty.base的一個基目錄,在Jetty9.1版本中新增加的。一個Jetty基目錄允許配置和web應用分開部署,可以方便升級系統。Jetty默認的配置基於兩個屬性:
jetty.home:這個屬性定義了Jetty的路徑,jar包,默認模塊和默認xml配置(典型有 start.jar,lib等)
jetty.base:這個屬性表示一個特殊Jetty服務應用的路徑,包括它的日志,配置和web應用(典型有 start.ini,start.d,logs和webapps)
  以下命令用於創建一個新的根路徑,同時激活HTTP connector和web 應用部署模塊,並且拷貝一個web應用例子來部署。
> JETTY_BASE=/tmp/mybase
> mkdir $JETTY_BASE
> cd $JETTY_BASE
> java -jar $JETTY_HOME/start.jar
 
WARNING: Nothing to start, exiting ...
 
Usage: java -jar start.jar [options] [properties] [configs]
java -jar start.jar --help # for more information
 
> java -jar $JETTY_HOME/start.jar --add-to-startd=http,deploy
 
INFO: server initialised (transitively) in ${jetty.base}/start.d/server.ini
INFO: http initialised in ${jetty.base}/start.d/http.ini
INFO: security initialised (transitively) in ${jetty.base}/start.d/security.ini
INFO: servlet initialised (transitively) in ${jetty.base}/start.d/servlet.ini
INFO: webapp initialised (transitively) in ${jetty.base}/start.d/webapp.ini
INFO: deploy initialised in ${jetty.base}/start.d/deploy.ini
MKDIR: ${jetty.base}/webapps
INFO: Base directory was modified
 
> cp $JETTY_HOME/demo-base/webapps/async-rest.war webapps/ROOT.war
> java -jar $JETTY_HOME/start.jar
 
2015-06-04 11:10:16.286:INFO::main: Logging initialized @274ms
2015-06-04 11:10:16.440:INFO:oejs.Server:main: jetty-9.3.0.v20150601
2015-06-04 11:10:16.460:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///tmp/mybase/webapps/] at interval 1
2015-06-04 11:10:16.581:WARN::main: async-rest webapp is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 11:10:16.589:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2015-06-04 11:10:16.628:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@1a407d53{/,[file:///tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-4510228025526425427.dir/webapp/, jar:file:///tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-4510228025526425427.dir/webapp/WEB-INF/lib/example-async-rest-jar-9.3.0.v20150601.jar!/META-INF/resources],AVAILABLE}{/ROOT.war}
2015-06-04 11:10:16.645:INFO:oejs.ServerConnector:main: Started ServerConnector@3abbfa04{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2015-06-04 11:10:16.646:INFO:oejs.Server:main: Started @634ms

  以上命令是Linux下的命令,簡單解釋:創建一個JETTY_BASE環境變量,並創建指定的文件夾,在此文件夾下運行start.jar時提示沒有可以啟動的東西,系統退出,此時輸入java -jar $JETTY_HOME/start.jar --add-to-startd=http,deploy命令為當前基目錄添加標准文件及文件夾,然后java -jar $JETTY_HOME/start.jar運行即可運行成功。在Windows下操作如下:

(1)可以手動創建一個空的文件夾,本例使用D:\temp\jetty
(2)在CMD中定位到當前目錄下,輸入java -jar D:\data\frame\jetty-distribution-9.3.11.v20160721\start.jar (注:D:\data\frame\jetty-distribution-9.3.11.v20160721目錄為我的電腦Jetty目錄,請輸入本機Jetty目錄)輸出信息如下:
 

(3)輸出結果同Linux,再次輸入java -jar D:\data\frame\jetty-distribution-9.3.11.v20160721\start.jar --add-to-startd=http,deploy,輸出信息如下:

(4)提示信息中說明創建了哪些文件,已經基目錄被修改等信息,此時到新建的基目錄下可以看到如下新增的東西:
jetty
    |-start.d
        |-deploy.ini
        |-http.ini
        |-server.ini
    |-webapps
(5)啟動后,會同樣看到404頁面,也可同上面的方法,拷貝ROOT項目到當前基目錄的webapps下

2.2.3 改變Jetty的端口

  通過在啟動命令中設置jetty.http.port屬性的值,可以讓Jetty運行在修改后的端口上。
> cd $JETTY_BASE
> java -jar $JETTY_HOME/start.jar jetty.http.port=8081
...

  另外,可以將要設置的端口屬性添加到start.ini或者start.d/http.ini文件中。默認情況,在start.d/http.ini文件中定義的jetty.http.port屬性可以被修改成另一個值。

提示

配置屬性信息通過如下方式獲得

  • 首先去start.d/http.ini文件中找jetty.http.port=8080配置信息,若找到配置端口即為指定端口
  • 根據模塊modules/http.mod文件找到指定配置默認為etc/jetty-http.xml,在此配置文件中有jetty.http.port配置信息,若找到即為此端口配置
  • 若上面兩個都沒有,則隨機一個沒有使用的端口

2.2.4 為HTTPS & HTTP2增加SSL

  可通過如下命令,添加並激活HTTPS和HTTP2模塊
> java -jar $JETTY_HOME/start.jar --add-to-startd=https,http2
[...]
 
> java -jar $JETTY_HOME/start.jar
[...]
 
2015-06-04 13:52:01.933:INFO:oejs.ServerConnector:main: Started ServerConnector@6f1fba17{SSL,[ssl, alpn, h2, http/1.1]}{0.0.0.0:8443}
[...]

 --add-to-startd:此命令在ini文件中設置有效的配置信息,使HTTPS和HTTP2支持SSL連接

  輸入java -jar $JETTY_HOME/start.jar --add-to-startd=https,http2命令后會提示下載一些jar包,輸入y按回車,最終提示信息如下,說明操作成功:

2.2.5 修改Jetty的HTTPS端口

  你可以通過增加jetty.ssl.port啟動參數來修改HTTPS的端口信息
> cd $JETTY_BASE
> java -jar $JETTY_HOME/start.jar jetty.ssl.port=8444

  除了在命令行增加參數的方法外,還可以在start.ini和start.d/*.ini文件中進行配置,所以如果用戶使用--add-to-startd命令來使HTTPS生效,同樣也可以在start.d/https.ini文件中進行修改。

2.2.6 更多的start.jar操作選項

  start.jar的工作是用來翻譯命令行內容的,start.ini和start.d目錄(包含其中的*.ini文件)生成一個classpath環境,各種屬性和配置可以使用Jetty相應的xml進行配置,更多的使用方法可以通過使用命令來獲得幫助。
> java -jar $JETTY_HOME/start.jar --help

2.3 部署Web應用

  Jetty支持熱部署,可以自動部署webapps目錄下的項目。標准的war文件和Jetty配置文件放置在webapps目錄下,通過以下規則進行熱部署
  • 例如一個包含 WEB-INF/ 子文件夾的example/文件夾做為一個標准的web應用進行部署,否則就按靜態資源部署,context路徑為/example(訪問路徑: http://localhost:8080/example/);若文件夾名字為ROOT,則訪問路徑為/;若文件夾名字末尾為.d則此文件夾被忽略(除非被特殊的配置文件引用)
  • 若一個文件example.war被部署在webapps下,則context路徑為example/,如果名字為ROOT則訪問路徑為/,如果example.war文件和example/文件夾同時存在,只有war文件會被部署(這個文件會被當做一個沒有被解壓的目錄來使用)
  • 一個像example.xml的配置文件,若文件中是標准的配置信息,也會被部署,文件中必須包含context path,如果context path和example.xml同時存在,只有example.xml會被部署。
  如果你有一個標准的web應用,可以直接將其拷貝到webapps文件夾下進行熱部署。

2.3.1 Jetty示例Web Application

  demo-base/webapps文件下的項目包含如下部署和附加的的文件:
 
ROOT/:這個文件夾包含各種靜態資源。包含Jetty歡迎頁面,默認訪問路徑為/
test.d:一個包含附加配置文件的文件夾,被test.xml使用用來為test.war增加額外的配置
test.xml:一個context配置文件,用來配置和部署test.war,包含上下文環境和test.d里面的配置附加的配置信息
test.war:在test.xml里面配置的示例web程序
async-rest.war:一個異步示例的web應用程序
test-jaas.war:一個使用JAAS身份驗證的web應用程序。
test-jaas.xml:用來配置test-jaas.war的配置文件
test-jndi.war:一個使用JNDI的示例應用
test-jndi.xml:用來配置test-jndi.war的配置文件
test-spec.war:一個使用注解,ServletContainerInitializers 和Servlet 3.0/3.1規范的示例應用
test-spec.xml:用來配置test-spec.war的配置文件
xref-proxy.war:使用代理的一個示例應用
example-moved.xml:一個演示MovedContextHandler重定向使用的示例應用

三、Jetty配置信息介紹

3.1如何配置jetty

3.1.1 Jetty POJO 配置

  Jetty的核心組件是POJO(Plain Old Java Objects),配置Jetty的過程就是實例化一個Jetty POJOs並對其進行配置的過程,可以通過如下實現:
  • 編寫Java代碼來直接實例化並配置Jetty對象,這稱為嵌入式Jetty。
  • 使用Jetty的xml配置文件,這是一個控制反轉框架模式,從xml文件中實例化Jetty對象。 etc/jetty.xml配置文件是Jetty的主要配置文件,但是也有很多etc/jetty-__feature__.xml類型的文件被Jetty使用
  • 使用第三方IOC框架,如Spring來實例化Jetty對象做為一個Spring Beans
  因為配置Jetty的主要方法是IoC,所以這個文檔主要介紹此種方法。

3.1.2 Jetty啟動配置文件

  Jetty使用如下配置文件來實例和啟動一個服務,通過start.jar處理
ini files:
Jetty啟動原理使用命令行,使用$JETTY_BASE/start.ini和$JETTY_BASE/start.d/*.ini文件來創建一個有效的命令參數參數如下:
  • 激活的模塊  --module=name
  • 通過name=value的來為Jetty的IOC配置屬性
  • XML files in Jetty IoC (or Spring) XML format
  • 一個標准的Java屬性文件包含額外的啟動屬性
  • 其他start.jar選項(see java -jar start.jar --help)
  • 一些JVM參數組合通過--exec,例如-Xbootclasspath.

提示

在Jetty9,只有Jetty基路徑下的配置文件被編輯,屬性才會被修改

mod files:
$JETTY_HOME/modules/*.mod文件包含各個模塊的定義,可以被--module=name命令激活,每個mod文件定義:
  • 模塊依賴如何排序以及激活
  • 被模塊需要並且要就在到classpath的jar包
  • 被模塊需要並且內容會被執行的xml文件
  • 被激活模塊需要的文件
  • 一個示例的ini文件,當被-add-to-start=name選項激活時使用

Note

常見典型的模塊配置信息通長很少被改動,*.mod文件通常位於$JETTY_HOME/modules/文件夾下,但是額外增加的或者編輯過的通常放在 $JETTY_BASE/module下,如果一個模塊需要被修改,最好的做法是在修改前從$JETTY_HOME/modules/拷貝*.mod到 $JETTY_BASE/modules/

XML files:  

xml文件一般用與IoC以及spring使用,用在命令行或者模塊定義中。xml文件里面的配置將被注入到描述服務的一個對象里。通常改變屬性的方法是改變對應的ini文件。xml文件通常放在$JETTY_HOME/etc/下,但是新增的或者被編輯的xml應該被放在 $JETTY_BASE/etc/下,如果xml配置文件有修改的必要,最好的做法是在修改前將xml文件從$JETTY_HOME/etc拷貝到$JETTY_BASE/etc/ 。
下圖是各種配置文件(ini, mod 和 XML)的關系

3.1.3 其它配置文件

  除了上面描述的配置文件以外,服務的配置信息可以使用如下的文件:
Context XML files:
  所有在/webapps目錄下用來被IoC使用的xml文件,用來部署相應的模塊,注入信息到HttpContext ,最終創建一個容器。這些可能是標准的web應用程序或定制上下文創建的特殊目的的處理器。
web.xml:
  web.xml用來定義和配置過濾器,servlet或者資源。Jetty WebAppContext組件使用這個XML文件用來:
  • 設置一個web項目的默認的根路徑
  • 通過WEB-INF/web.xml進行特殊的配置
  • Interpret descriptor fragments included in the META-INF directory of Jar files within WEB-INF/lib.

Note

通常web應用的web.xml文件應該在WEB-INF/web.xml位置被發現,Jetty還支持多個web.xml,可以在 WEB-INF/web.xml文件加載前或者加載后加載(使用方法見test.xml)

Property Files:
  標准的Java配置文件,同樣適用於Jetty配置:
  • 可以為Jetty IoC增加參數
  • 配置默認日志信息(StdErrLog),其他日志框架也可以通過配置被使用(例如,log4j)
  • 數據庫的登錄配置信息等 

3.1.4 Jetty IoC XML使用

  為了理解Jetty IOC XML使用方法,如下面的示例Java中,嵌入式Jetty服務器實例並配置
//
//  ========================================================================
//  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//
package org.eclipse.jetty.embedded;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.ServletContextHandler;
public class ExampleServer
{
    public static void main( String[] args ) throws Exception
    {
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8080);
        server.setConnectors(new Connector[] { connector });
        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");
        context.addServlet(HelloServlet.class, "/hello");
        context.addServlet(AsyncEchoServlet.class, "/echo/*");
        HandlerCollection handlers = new HandlerCollection();
        handlers.setHandlers(new Handler[] { context, new DefaultHandler() });
        server.setHandler(handlers);
        server.start();
        server.join();
    }
}

 

注意事項:
  • 注意Jetty的最低使用的jdk版本,最新版本使用jdk1.8
  • HelloServlet是一個繼承了HttpServlet的servlet
  • 運行成功后程序會被掛起,等待用戶連接,在瀏覽器中輸入http://localhost:8080/hello即可訪問
  Jetty IoC XML format也允許用戶通過XML來實例化應用服務而不用寫任何代碼(下面配置文件的具體使用方法以后會講到)
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="ExampleServer" class="org.eclipse.jetty.server.Server">
  <Set name="connectors">
    <Array type="org.eclipse.jetty.server.Connector">
      <Item>
        <New class="org.eclipse.jetty.server.ServerConnector">
          <Arg><Ref refid="ExampleServer"/></Arg>
          <Set name="port">8080</Set>
        </New>
      </Item>
    </Array>
  </Set>
  <New id="context" class="org.eclipse.jetty.servlet.ServletContextHandler">
    <Set name="contextPath">/hello</Set>
    <Call name="addServlet">
      <Arg>org.eclipse.jetty.embedded.HelloServlet</Arg>
      <Arg>/</Arg>
    </Call>
  </New>
  <Set name="handler">
    <New class="org.eclipse.jetty.server.handler.HandlerCollection">
      <Set name="handlers">
        <Array type="org.eclipse.jetty.server.Handler">
          <Item>
            <Ref refid="context" />
          </Item>
          <Item>
            <New class="org.eclipse.jetty.server.handler.DefaultHandler" />
          </Item>
        </Array>
      </Set>
    </New>
  </Set>
</Configure>

 

3.2 可以在Jetty中配置什么

  這一節將介紹Jetty常用的配置。

3.2.1 配置服務

  Server實例是Jetty服務的重要組成部分,它為其它Jetty組件提供服務和生命周期管理。在標准的Jetty應用中,核心的配置信息在etc/jetty.xml文件中 ,但是你也可以在配置文件中添加其它配置 ,包括:
ThreadPool:
  服務器實例提供了一個默認ThreadPool實例,用來供其它組件調用。配置線程池的主要參數有最大和最小數量的設置,設置在start.ini文件或者start.d/server.ini文件中。
Handlers:
  一個Jetty服務器可以只有一個處理程序實例來處理傳入的HTTP請求。然而一個處理程序可能是一個容器或包裝其他處理程序形成一個樹的處理程序。在etc/jetty.xml文件中配置的默認的處理程序包含處理程序集合和一個默認的處理程序,根據路徑找到相應的處理程序,默認的處理器處理404錯誤。其他配置信息可以增加到處理樹中(例如,jetty-rewrite.xml, jetty-requestlog.xml), 或者配置一個組件用於熱部署處理(例如,jetty-deploy.xml) 。
Server Attributes:
  服務器可以通過字符串來映射到一個對象上,如果一個對象實現了LifeCycle接口,那么這個對象可以監聽這個Jetty服務的啟停。通常服務器的屬性保存在服務器生命周期內。
Server fields:
  服務器也有一些特殊的的配置屬性,配置在start.ini或者start.d/server.ini文件中,除了控制屬性外還有發送時間和http響應的版本。
Connectors:
  服務器擁有一個連接的集合,用來接收http請求,和其它Jetty支持的協議請求,下一章節將要介紹配置連接。對於服務器可以設置所有的連接也可以增加或者刪除個別連接。
Services:
  服務器能容納額外的服務對象,有時作為屬性,但經常做為有生命周期的bean。

3.2.2配置連接

  Jetty服務器連接器是一個網絡端點接受連接一個或多個協議產生Jetty服務器的請求或消息。在標准Jetty服務器中,可以通過額外的文件增加Jetty服務器支持的協議,例如http.ini,https.ini 和jetty-http2.xml,連接的配置一般都是典型的,如下:
Port:
  監聽TCP/IP連接請求的端口,使用jetty.http.port(或者jetty.ssl.port)屬性進行配置,如果沒有配置默認8080(TLS默認8443)。
Host:
  您可以配置一個主機的主機名或IP地址來識別一個特定的網絡接口的監聽。如果沒有設置,或者設置為0.0.0.0,連接器將監聽所有主機。可以通過xml文件中jetty.host的這個屬性進行設置。
Idle Timeout:
  時間以毫秒為單位,一個連接的超時時間。
HTTP Configuration:
  通過HttpConfiguration 實例來配置HTTP連接(包含HTTP, HTTPS 和HTTP2),可以獨立於特定的網絡協議,標准的Jetty服務通過jetty.xml來配置一個單例的HttpConfiguration對象。
SSL Context Factory:
  通過本地的密鑰來保證ssl連接的安全性。

Note

虛擬主機不能配置連接,用戶應該通過虛擬主機的context來實現它們的相應。

Note

Jetty9同時支持連接協議(HTTP,HTTPS,AJP,SPDY)和自然連接(NIO或者BIO),Jetty9以后只有一個主要的連接器ServerConnector

3.2.3配置上下文環境

一個Jetty環境包含一組處理器處理指定路徑的請求。一個Jetty環境可以包含默認處理器和用戶自定義處理器。

Note

servlet規范定一個web應用。在Jetty規范中一個標准的web項目必須有一個標准的WEB-INF/web.xml文件,用來配置classpath,資源,session處理,登錄,以及servlet,jsp,以及靜態資源。標准的web應用需要很少的額外的配置文件。

常見的上下文配置:
contextPath:
  contextPath 是URL的前綴。例如一個contextPath 是/foo,它將處理 /foo, /foo/index.html, /foo/bar/,and /foo/bar/image.png等請求,但是它不會處理像/,/other/,or /favicon.ico這樣的請求,若contextPath是/,則為根contextPath。contextpath可以被默認設置(默認為部署的文件名),也可以在xml里面或者代碼里面進行設置,或者在WEB-INF/jetty-web.xml文件中設置。
virtualHost:
  配置監聽主機ip或名稱,沒有配置的將不會被監聽到。
classPath:
  配置類路徑,標准的類路徑為 WEB-INF/lib和WEB-INF/classes ,也可以增加額外的路徑到classpath下。
attributes:
  配置屬性,可以傳遞到實體類中,比如javax.servlet.context.tempdir屬性用來配置臨時目錄。
resourceBase:
  配置資源,這個配置是一個目錄,包含各種靜態資源信息,可以是圖片或者HTML頁面。

3.2.3.1 通過API配置上下文

在嵌入式的server,用戶可以通過ContextHandler API來配置上下文,示例如下:
//
//  ========================================================================
//  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//
package org.eclipse.jetty.embedded;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
public class OneContext
{
    public static void main( String[] args ) throws Exception
    {
        Server server = new Server( 8080 );
        // Add a single handler on context "/hello"
        ContextHandler context = new ContextHandler();
        context.setContextPath( "/hello" );
        context.setHandler( new HelloHandler() );
        // Can be accessed using http://localhost:8080/hello
        server.setHandler( context );
        // Start the server
        server.start();
        server.join();
    }
}

 

3.2.3.2 通過Ioc XML配置上下文

  用戶可以創建一個IoC的XML(或使用spring的Jetty插件)
<?xml version="1.0"  encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC
    "-//Mort Bay Consulting//DTD Configure//EN"
    "http://www.eclipse.org/jetty/configure_9_0.dtd">
<!--
  Configure a custom context for serving javadoc as static resources
-->
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
  <Set name="contextPath">/javadoc</Set>
  <Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/javadoc/</Set>
  <Set name="handler">
    <New class="org.eclipse.jetty.server.handler.ResourceHandler">
      <Set name="welcomeFiles">
        <Array type="String">
          <Item>index.html</Item>
        </Array>
      </Set>
      <Set name="cacheControl">max-age=3600,public</Set>
    </New>
  </Set>
</Configure>

 

3.2.4 配置web應用

servlet規范定義了一個web應用程序,當調用打包為一個WAR文件(web應用程序存檔),Jetty通過如下進行配置:
  • 初始化classpath,在WEB-INF/lib和WEB-INF/classes下。
  • 根據標准的WEB-INF/web.xml進行解析初始化參數,過濾器,監聽器,歡迎頁面等信息。
  • WEB-INF/jetty-web.xml文件可能包含Jetty IoC的配置。

3.2.4.1 配置contextpath

  可以增加一個WEB-INF/jetty-web.xml文件用來配置classpath
<?xml version="1.0"  encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC
    "-//Mort Bay Consulting//DTD Configure//EN"
    "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <Set name="contextPath">/contextpath</Set>
</Configure>

   還有一種做法是,不用增加配置文件,在war文件同目錄,建一個同名的xml文件,內容如下:

<?xml version="1.0"  encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC
    "-//Mort Bay Consulting//DTD Configure//EN"
    "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test.war</Set>
  <Set name="contextPath">/test</Set>
</Configure>

   配置例子可以參照$JETTY_HOME/webapps/test.xml

3.2.4.2 Web應用部署

Jetty能夠部署各種Web應用程序的格式。這是通過 掃描${jetty.base}/webapps 文件夾下
一個Context可以有如下
  • 一個標准的war文件(必須以war結尾)
  • 一個標准的web應用(必須有{dir}/WEB-INF/web.xml 文件)
  • 一個包含靜態資源的文件夾
  • 一個Jetty描述XML,引用一個web應用
新WebAppProvider將試圖避免雙重部署,以及其他需要注意的方面,如下:
  • 隱藏文件將被忽略(以.開頭的文件)
  • 以.d開頭的文件夾將被忽略
  • 如果一個文件夾和war名字一樣,則只有war會部署
  • 如果一個文件夾和同名xml配置,則xml配置的會被部署
  • 如果一個war文件和xml文件同名,則xml配置的會被部署

3.2.4.3 設置身份驗證區域

  身份驗證方法和域名校驗可以在web.xml里面進行描述:
...
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>Test Realm</realm-name>
</login-config>
...

   這個例子使用名為Test Realm.的驗證,但是沒有說明其是怎么實現的,在Jetty中有幾種實現方式,其中一種是HashLoginService可以讀取登錄用戶,並在配置文件中查找,為了配置HashLoginService用來匹配Test Realm,可以配置$JETTY_BASE/etc/test-realm.xml文件,並且該文件必須在start.ini或者start.d/server.ini中設置。

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
    <!-- =========================================================== -->
    <!-- Configure Authentication Login Service                      -->
    <!-- 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)/webapps/test.xml for an    -->
    <!-- example).                                                   -->
    <!-- =========================================================== -->
    <Call name="addBean">
      <Arg>
        <New class="org.eclipse.jetty.security.HashLoginService">
          <Set name="name">Test Realm</Set>
          <Set name="config"><Property name="jetty.demo.realm" default="etc/realm.properties"/></Set>
          <Set name="refreshInterval">0</Set>
        </New>
      </Arg>
    </Call>
    <Get class="org.eclipse.jetty.util.log.Log" name="rootLogger">
      <Call name="warn"><Arg>demo test-realm is deployed. DO NOT USE IN PRODUCTION!</Arg></Call>
    </Get>
</Configure>

   通過創建和配置LoginService到web應用中,當部署應用時,會通過名字去尋找匹配的登錄Service。 

 

  以上是翻譯的第一部分,Jetty所有目錄信息見:http://www.cnblogs.com/yiwangzhibujian/p/5832294.html,后面幾個部分比較多可能會分幾篇進行翻譯,很多地方翻譯的時候都不明白是如何使用的,因此有可能翻譯不到位,估計等我全部看完后才會理解,那時候我會根據自己的理解寫一點新手教程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM