軟體開發往往是這樣:最開始的 90% 代碼占用了開始的 90% 的開發時間;剩下10% 代碼同樣需要 90% 的開發時間。
目錄 - 前言
- 正文
- 何為JAX-RS(1.0和2.0)
- JSR 311
- JSR 339
- 落地産品
- Jersey
- 1.x和2.x的差別
- jersey-client
- 使用示例
- jersey-client vs HttpClient
- 總結
- 聲明
- 何為JAX-RS(1.0和2.0)
- JSR 311
- JSR 339
- 落地産品
- Jersey
- 1.x和2.x的差別
- jersey-client
- 使用示例
- jersey-client vs HttpClient
- 聲明
前言
在
Spring
大行其道的今天,很多人對Java的RESTful規範
JAX-RS
可能比較陌生甚至未曾聽聞,當然這也是能被“了解”的,畢竟Spring似乎現在已是
JavaEE
的事實标準。
現在有越來越多的公司希望能以簡單而又貼合Web架構本身的方式公開Web API,是以REST變得越來越重要和流行。使用Ajax進行通信的富浏覽器端也在朝這個目标不斷邁進。這個架構原則提升了網際網路的可伸縮性,無論何種應用都能從該原則中受益無窮。
正文
其實關于
JAX-RS
的資料并不算多,根據存在即合理原則我們需要承認它的重要性肯定比不上Spring,但是由于老外一般喜歡使用JavaEE規範技術,是以使得一些開源社群架構使用的均是基于
JAX-RS
的實作,是以對它來個簡單的了解還是很有必要的。
何為JAX-RS(1.0和2.0)
JAX-RS是
JAVA EE6
引入的一個新技術,它的英文全稱為
Java API for RESTful Web Services
,它的核心概念是Resource,即面向資源。JavaEE 6于2019年12月份正式釋出。
JSR 311
它被稱為JAX-RS 1.0标準,它提供一套JSR311标準API:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
複制

這些注解和
Spring MVC
的
@RequestMapping、@RequestParam、@PathVariable...
何其相似,各位可以類比起來學習,本處不必一一展開。但是注意一點,SpringMVC在開發REST應用時,是不支援JSR311标準的。
JSR 339
它是JAX-RS 2.0版本,于2018年釋出。它不僅定義了一套用于建構 RESTful 網絡服務的 API,同時也通過增強用戶端 API 功能簡化了REST 用戶端的建構過程。
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>2.1.6</version>
</dependency>
複制
規範API的向下相容度還是非常好的,它在1.0規範的基礎上對Client的建構做了增強,如提供了
javax.ws.rs.client.ClientBuilder
、
javax.ws.rs.client.WebTarget
等實用API。
落地産品
每個JavaEE規範都應對應其落地産品的實作,就像JPA的實作落地實作有
Hibernate
、
TopLink
等。基于
JAX-RS
實作的架構有
Jersey、RESTEasy
,當然還有
Apache CXF
。但是,因為Jersey是最早的實作(出現得比JSR311還早),是JSR311參考的主要對象,是以,可以說Jersey就是事實上的标準,就像Hibernate是JPA的事實标準一樣~
值得一提的是:RESTEasy是由JBoss公司開發的,是以将用RESTEasy架構實作的應用部署到JBoss伺服器上,可以實作很多額外的功能(但很顯然,JBoss已經退出了曆史舞台)。
Jersey
Jersey是一個REST架構,既然是REST架構,那自然提供了REST服務相關的一切東西。是以在使用過程中,你可以同Spring MVC做對比,部署到Servlet容器上即可運作,形如這樣:
@Path("/api/v1/user")
public class UserResource{
@GET
@Path("/{username}")
@Consumes({"application/json", "application/xml"})
@Produces("application/json")
public String getUser(@PathParam("username") String username){
...
}
}
複制
作為服務端,它使用的庫是:
1.x:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19.4</version>
</dependency>
2.x:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.30.1</version>
</dependency>
複制
1.x和2.x的差別
1.x在2017年5月釋出其最後一個版本
1.19.4
後就已經壽終正寝了,是以不建議再使用。2.x從2013年釋出疊代至今,是現在推薦的使用方式(可見它倆重疊開發了好幾年)。
1.x和2.x版本互不相容,核心API均出現了一定的差異性,舉例如下:
- 實作規範:
- 1.x:實作的JAX-RS 1.0規範,也就是JSR 311
- 2.x:實作的JAX-RS 2.0規範,也就是JSR 339
- Servlet容器全類名:
- 1.x:
(sun公司)com.sun.jersey.spi.container.servlet.ServletContainer
- 2.x:
(glassfish公司)org.glassfish.jersey.servlet.ServletContainer
- 1.x:
- 資源掃描:
- 1.x:
com.sun.jersey.config.property.packages
- 2.x:
jersey.config.server.provider.packages
- 1.x:
- 注解支援:
- 1.x:不支援Servet3.x的注解
- 2.x:支援注解如
來掃描jersey的資源@WebServlet
- …
說明:glassfish是一款web應用伺服器,和tomcat一樣,也是一款優秀的Servlet容器。它既是EJB容器也是WEB容器,由Sun公司開發(現Oracle贊助)。
jersey-client
以上大體介紹了jersey作為Server端技術的實施,接下來介紹其用戶端API,這便是
jersey-client
工程。Jersey的用戶端API能夠讓我們非常友善的建立出REST的Web服務用戶端,不管是用戶端應用,還是用于測試的代碼,都是非常容易和舒服的。
特别說明:本文講解、執行個體使用的
jersey-client
版本是1.x版本,1.x版本,1.x版本
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19.4</version>
</dependency>
複制
它的jar包依賴情況如下:
使用示例
@Test
public void fun1() {
// 1、建立一個Client
DefaultClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
// 2、準備一個WebResource,等待發送請求(注意:http字首不能省)
// WebResource webResource = client.resource( URI.create("www.baidu.com"));
WebResource resource = client.resource("http://www.baidu.com");
// 3、發送get/post請求擷取資源
// String result = resource.get(String.class);
// System.out.println(result);
// 若你想擷取響應詳情,可以使用ClientResponse
ClientResponse response = resource.get(ClientResponse.class);
System.out.println(response.getStatus());
System.out.println(response.getHeaders());
System.out.println(response.getLocation());
System.out.println(response.getEntity(String.class));
}
複制
運作程式,控制台列印:
200
{Server=[bfe], Content-Length=[2381], Date=[Sat, 14 Mar 2020 09:55:47 GMT], Content-Type=[text/html]}
null
<!DOCTYPE html> ... // 百度首頁的html,略
複制
說明:Client的建構屬于昂貴資源,是以請重複使用它,它底層使用的 java.net.HttpURLConnection
進行請求發送的
jersey-client vs HttpClient
在Java中,
REST Client
實作方式有多種,比如JBoss RestEasy、 Sun Jersey、Dropwizard、Apache HTTPClient、OkHttp等等。很多人直接使用
Apache Http Client
, 我并不推薦直接使用這個庫,主要是因為這個庫相對比較底層,需要自己處理的東西很多,,API也相對繁瑣。
另外,對于JDK源生的
URLConnection
和
Apache HTTPClient
附上一個對比圖:
總體上HttpClient比HttpURLConnection功能更加豐富且好用,但是更加占用記憶體和CPU資源,大家都知道!當然,若你在Spring環境下需要使用Rest Client,那就用
RestTemplate
吧~
總結
本文介紹了
JAX-RS
标準JavaEE技術,并且對JSR 311/JSR 339等做了一個簡單的科普,示例了
jersey-client
的使用介紹。個人覺得過于國内程式員來說
JAX-RS
技術(jersey的使用)不用太過于深究,淺嘗辄止即可。