1. 程式人生 > >Jetty使用教程(一)開始使用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版本
版本YearHomeJVM協議ServletJSP狀態

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

JSRNameIncluded with jetty-9.0.xPluggable

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

LocationDescription

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.。然而在JETTYHOME/webappswebJetty404JETTY_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 [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 JETTYHOME/start.jaraddtostartd=http,deployjavajarJETTY_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配置資訊,若找