原地址:http://blog.csdn.net/li575098618/article/details/47853263
Jersey 1.0 是一個開源的、可以用於生產環境的 JAX-RS(RESTful Web Services 的 Java API 規范,JSR-311)實現。通過 Jersey 可以很方便的使用 Java 來創建一個 RESTful Web Services。
一篇早期的技術文章——《在 Java 中實現 RESTful Web Services》,介紹了 RESTful,JAX-RS 以及 Jersey。它同樣向你展示了怎樣使用 Java 來寫一個遵循 JAX-RS 標准的 RESTful Web Services。另一篇文章《在 Jersey 1.0 中為 RESTful Web Services 配置 JSON》說明了怎么通過 Jersey 1.0 來配置數據格式為 JSON(JavaScript 對象符號)。
在這篇文章中,你將學到怎么使用 Jersey 1.0.2 客戶端 API 來創建基於 HTTP 的 RESTful Web Services。Jersey 1.0.2 客戶端 API 是一個易於使用的,高層的的 Java API,可以幫助你編寫任何基於 HTTP 的 RESTful Web Services。這個 API 構建於一個統一的接口規范,其中的一個關鍵就是 REST 原則。這個統一的接口規范意味着一個基於 REST 的應用程序不管它訪問任何 URL,那些 URL 的接口都必須是一樣的。
Jersey 客戶端 API 基礎
要開始使用 Jersey 客戶端 API,你首先需要創建一個 com.sun.jersey.api.client.Client 類的實例。下面是最簡單的方法:
import com.sun.jersey.api.client.Client; Client client = Client.create();
Client 類是創建一個 RESTful Web Service 客戶端的主要配置點。你可以使用它來配置不同的客戶端屬性和功能,並且指出使用哪個資源提供者。創建一個 Client 類的實例是一個比較昂貴的操作,所以盡量避免創建一些不需要的客戶端實例。比較好的方式是盡可能地復用已經存在的實例。
當你創建完一個 Client 類的實例后,你可以開始使用它。無論如何,在發出請求前,你需要創建一個 WebResource 對象來封裝客戶端所需要的 Web 資源。例如,以下代碼為一個完整地址為http://example.com/base 的 Web 資源創建了一個 WebResponse 對象:
import com.sun.jersey.api.client.WebResource; WebResource webResource = c.resource("http://example.com/base");
通過使用 WebResource 對象來創建要發送到 Web 資源的請求,以及處理從 Web 資源返回的響應。例如,你可以使用 WebResource 對象來發送 HTTP GET、PUT、POST 以及 DELETE 請求。
GET 請求:使用 WebResource 類的 get() 方法來提交一個 HTTP GET請求到 Web 資源:
String s = webResource.get(String.class);
這表示如果 WebResource 對象的 URL 是 http://example.com/base,那么一個 HTTP GET 請求將會發送到地址為 http://example.com/base 的資源。如果你熟悉命令行下的 HTTP 工具 curl,那么你可以知道:
String s = webResource.get(String.class);
相應的 curl 命令如下
curl http://example.com/base
你還可以指定 get() 請求時的查詢參數。例如,下面的代碼在 get() 請求中指定了兩個查詢參數:
MultivaluedMap queryParams = new MultivaluedMapImpl(); queryParams.add("param1", "val1"); queryParams.add("param2", "val2"); String s = webResouce.queryParams(queryParams).get(String.class);
相應的 curl 命令如下:
curl http://example.com/base?param1=val1¶m2=val2
你還可以指定響應所能接受的 MIME 類型。例如,下面的代碼指定了響應的 MIME 類型只能為文本:
String s = webResource.accept("text/plain").get(String.class);
相應的 curl 命令如下:
curl -HAccept:text/plain http://example.com/base
另外,你還可以獲取對應請求的 HTTP 狀態碼,例如下面這個例子展示獲取一個請求所返回的文本實體與狀態碼:
ClientResponse response = webResource.accept("text/plain") .get(ClientResponse.class); int status = response.getStatus(); String textEntity = response.getEntity(String.class);
ClientResponse 對象代表了一個客戶端收到的 HTTP 響應。
PUT 請求:使用 WebResource 類的 put() 方法來提交一個 HTTP PUT 請求到 Web 資源。例如下面的代碼展示了請求發送一個文本實體 foo:bar 到指定的 Web 資源:
ClientResponse response = webResource.type("text/plain").put(ClientResponse.class, "foo:bar");
相應的 curl 命令如下:
curl -XPUT -HContent-type:text/plain --data "foo:bar" http://example.com/base
同樣,你也可以在使用 put() 方法發送請求時指定查詢參數,方法與使用 get() 方法時指定查詢參數一樣。在下面的例子中,把在之前 get() 方法示例中使用過的兩個同樣的查詢參數指定到了一個 put() 請求中:
MultivaluedMap queryParams = new MultivaluedMapImpl(); queryParams.add("param1", "val1"); queryParams.add("param2", "val2"); ClientResponse response = webResource.queryParams(queryParams).put(ClientResponse.class, "foo:bar");
相應的 curl 命令如下:
curl -XPUT -HContent-type:text/plain --data "foo:bar" http://example.com/base?param1=val1¶m2=val2
POST 請求:一個 POST 請求相當於一個 GET 請求和一個 PUT 請求的綜合,也就意味着,你可以使用 POST 請求來發送一個實體到指定的 Web 資源並且接收另一個實體。使用 WebResource 類的 post() 方法來發送一個 HTTP POST 請求到指定的 Web 資源。下面的例子展示了發送一個帶有查詢參數以及進行了 URL 編碼的表單數據的 POST 請求:
MultivaluedMap formData = new MultivaluedMapImpl(); formData.add("name1", "val1"); formData.add("name2", "val2"); ClientResponse response = webResource.type("application/x-www-form-urlencoded") .post(ClientResponse.class, formData);
相應的 curl 命令如下:
curl -d name1=val1 -d name2=val2 http://example.com/base
DELETE 請求:使用 WebResource 類的 delete() 方法來發送珍上 HTTP DELETE 請求到指定的 Web 資源。例如,下面的例子展示刪除一個 URI 為 http://example.com/base/user/123 資源:
ClientResponse response = webResource.path("user/123") .delete(ClientResponse.class);
相應的 curl 命令如下:
curl -XDELETE http://example.com/base/user/123
另外,WebResource.path() 方法可以在所有 HTTP 請求中使用,它可以讓你給要請求的 Web 資源指定一個額外的路徑。另一個 WebResouce 類的方法 header() 可以給你的請求添加 HTTP 頭部信息。
配置 Jersey 客戶端
在發送請求前,你還需要配置 Jersey 客戶端,這涉及到注冊提供程序。另外你也可以添加過濾器 ,這是可選的操作。你可以查閱 Jersey 1.0.2 客戶端 API 來得到所有可選操作的概覽。
注冊提供程序:在 JAX-RS 中,提供程序是指一個 JAX-RS 擴展的實現。一個提供程序類被一個 @Provier 注解所標注。Jersey 服務器實現了提供程序的基礎結構。在實現 JAX-RS 時,Jersey 包含了標准的提供程序類。Jersey 客戶端 API 重用了與 Jersey 服務器同樣的提供程序基礎結構。無論如何,你都必須顯式的注冊所有非標准的提供程序,因為在客戶端不會自動進行類庫路徑的搜索。
要注冊一個提供程序,你需要將提供程序的類添加到 ClientConfig 對象用來創建 Client 類的實例。ClientConfig 類定義了通用的屬性名稱、功能、屬性、提供程序類,以及可以被 Client 對象使用的單例提供程序實例。例如下面的代碼注冊了一個供 Client 對象使用的 JSON 提供程序:
ClientConfig config = new DefaultClientConfig(); config.getClasses().add(JSONRootElementProvider.class); Client client = Client.create(config);
注意 DefaultClientConfig 類的使用,它定義了默認的 Client 配置
添加過濾器:另外一個在配置 Client 過程中可選的操作是添加過濾器到 Client 實例。過濾器動態的攔截到一個資源類的請求和響應,並且可以修改請求或響應。Jersey 客戶端 API 提供了一些工具類過濾器。其中之一是 LoggingFilter,它實現了一個日志記錄過濾器。你可以使用一個日志記錄過濾器來跟蹤客戶端與服務器之間的通信,這在調試的時候往往很有用。下面的代碼展示了怎么添加一個日志記錄過濾器到客戶端:
import com.sun.jersey.api.client.filter.LoggingFilter client.addFilter(new LoggingFilter());
一個基於 Jersey 客戶端的示例
Twitter: Twitter 是一個允許你與朋友、同事、家人或者其他人之間交換簡短信息的服務。那些信息是用來回答“你在干什么”這個問題。下面是通過 Twitter 顯示一些信息的例子:
Twitter 提供了一個公開的 Twitter API ,你可以通過這個 API 來使用編程的方式發表或查看 Twitter 消息,或使用這個服務的其他功能。如果你要使用 Twitter API,有一件事你必須考慮到是Twitter的認證和安全機制和要求。
*Twitter 認證與安全*:Twitter 使用基本的 HTTP 認證語法。這意味着如果你要通過 Twitter API 來存取 Twitter,你需要在你的請求中添加認證頭。如果你需要更安全的通信,那么你同樣可以使用 SSL(Secure Sockets Layer) 來與服務器進行通信。你只需要簡單的依照下面的代碼做即可:
ClientConfig config = new DefaultClientConfig(); SSLContext ctx = SSLContext.getInstance("SSL"); ctx.init(null, myTrustManager, null); config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hostnameVerifier, ctx)); Client client = Client.create(config);
創建 Client 和 WebResource 對象的代碼
import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; private static final String BaseURI = "https://twitter.com"; private final WebResource wr; Client client = Client.create(config); wr = client.resource(BaseURI);
配置客戶端的代碼
import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; ClientConfig config = new DefaultClientConfig(); config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hv, ctx)); config.getClasses().add(JAXBContextResolver.class);
發出一個 GET 請求的代碼
public List<StatusBean> getFriendsTimelineJson() { return wr.path("statuses/friends_timeline.json") .header(AUTHENTICATION_HEADER, authentication) .accept(MediaType.APPLICATION_JSON_TYPE) .get(new GenericType<List<StatusBean>>() { }); }