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 ProfileJSR | 名稱 | 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 [email protected]{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.。然而在
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 [email protected]{/,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 [email protected]{/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 [email protected]{/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 [email protected]{/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 [email protected]{/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 [email protected]{/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 [email protected]{/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 [email protected]{/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 [email protected]{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 [email protected](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 [email protected]{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 [email protected]{/,[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 [email protected]{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
(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配置資訊,若找