1. 引言
Jersey 是一個功能齊全的開源框架,用於使用 Java 開發 Web 服務和客户端。通過使用 Jersey,我們可以創建支持 HTTP 功能集完整的一系列強大 Web 應用程序。
在本文中,我們將探討 Jersey 的兩個特定功能:<em @FormDataParam</em> 和 <em @FormParam</em> 註解。雖然這兩種註解具有相似的特性,但它們之間存在顯著差異,正如我們將在下面看到。
2. 背景
有多種方法可以實現客户端和服務器之間的數據交換。其中最流行的兩種是 XML 和 JSON,但並非唯一選擇。
編碼後的表單數據是當客户端是一個網頁時,在客户端和服務器之間傳輸數據的一種格式化方式。 這是因為 HTML 使得定義各種輸入(文本、複選框、下拉菜單等)變得容易,並可以將這些數據發送回遠程服務器。
這就是 @FormDataParam 與 @FormParam 註解發揮作用的地方。 它們都用於在 Jersey 服務器應用程序中處理表單數據,但兩者之間存在一些重要的差異。
現在我們已經瞭解了這兩個註解的背景知識,接下來讓我們看看如何使用它們以及它們之間的差異。
3. 使用 @FormParam 標註
簡而言之,我們使用 @FormParam 標註,當API期望接收URL編碼的數據時。 讓我們來看一個僅包含文本字段的簡單HTML表單:
<form method="post" action="/example1">
<input name="first_name" type="text">
<input name="last_name" type="text">
<input name="age" type="text">
<input type="submit">
</form>此表單包含三個字段:姓名、姓氏和年齡。它還使用 HTTP 的 POST 方法將表單數據發送到位於 /example1 的 URL。
要使用 Jersey 處理此表單,我們將定義以下端點:
@POST
@Path("/example1")
public String example1(
@FormParam("first_name") String firstName,
@FormParam("last_name") String lastName,
@FormParam("age") String age)
{
// process form data
}請注意,我們為 HTML 表單中的每個字段使用註釋。 無論表單有多少或何種類型的字段,這種方法都有效。 通過使用 @FormParam 註解,Jersey 會將每個字段的值綁定到相應的類方法參數。
在實踐中,表單編碼數據與 MIME 類型 application/x-www-form-urlencoded 相關聯。 在瀏覽器和我們的服務之間傳輸的數據如下所示:
first_name=john&last_name=smith&age=42這種方法的主要優勢在於,數據易於處理,因為它只涉及文本,不包含二進制數據。此外,由於字符串可以作為 URL 中的查詢參數傳遞,因此該方法可以使用 HTTP GET 動詞。但是,通過 URL 傳遞表單數據時,應謹慎,因為它可能包含敏感數據。
4. 使用 @FormDataParam 註解
相比之下,@FormDataParam 註解更靈活,可以處理任何文本和二進制數據的組合。在實踐中,這對於諸如通過 HTML 表單的文件上傳等場景非常有用。
下面我們來看一個使用 @FormDataParam 註解的示例表單。首先,我們需要從 Maven Central 導入 jersey-media-multipart 模塊:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>3.1.3</version>
</dependency>現在,讓我們為我們上面創建的 HTML 表單添加一個文件上傳字段:
<form method="post" action="/example2" enctype="multipart/form-data >
<input name="first_name" type="text">
<input name="last_name" type="text">
<input name="age" type="text">
<input name="photo" type="file">
<input type="submit">
</form>請注意,我們現在指定了 form 元素中 multipart/form-data 的編碼類型。這樣做是為了確保 Web 瀏覽器以我們的服務期望的格式發送數據。
接下來,在我們的應用程序中,我們將創建以下端點來處理來自此表單的數據:
@POST
@Path("/example2")
public String example2(
@FormDataParam("first_name") String firstName,
@FormDataParam("last_name") String lastName,
@FormDataParam("age") String age,
@FormDataParam("photo") InputStream photo)
{
// handle form data
}請注意,現在每個表單字段都使用了 @FormDataParam 註解。我們還使用 InputStream 作為參數類型,用於處理二進制數據。
與之前的示例不同,這裏每個字段及其值被組合成部分。每個部分都用一個唯一的標記分隔,允許 Jersey 輕鬆識別每個參數並將其綁定到相應的類方法參數。
例如,從這個表單發送的原始消息可能如下所示:
------WebKitFormBoundarytCyB57mkvJedAHFx
Content-Disposition: form-data; name="first_name"
John
------WebKitFormBoundarytCyB57mkvJedAHFx
Content-Disposition: form-data; name="last_name"
Smith
------WebKitFormBoundarytCyB57mkvJedAHFx
Content-Disposition: form-data; name="age"
42
------WebKitFormBoundarytCyB57mkvJedAHFx
Content-Disposition: form-data; name="photo"; filename="john-smith-profile.jpeg"
Content-Type: image/jpeg
------WebKitFormBoundarytCyB57mkvJedAHFx--這種方法的關鍵優勢在於,我們可以同時發送文本和二進制數據。 然而,與使用傳統表單編碼數據相比,它也存在一些缺點。
首先,我們只能使用 HTTP POST 動詞 這種類型。 這是因為二進制數據無法編碼並傳遞到 URL 字符串中。 其次,報文大小比傳統表單編碼數據大得多。 如上例所示,用於定義分隔符和標題所需的額外文本會顯著增加報文大小。
5. 結論
在本文中,我們探討了 Jersey 庫中兩種不同的註解:<em @FormParam</em>> 和 <em @FormDataParam</em>>。 這兩種註解都用於處理應用程序中的表單數據,但正如我們所見,它們有着截然不同的目的。
<em @FormParam</em>> 在發送表單編碼數據時更適用。它可以使用 GET 或 POST 動詞,但只能包含文本字段。另一方面,<em @FormDataParam</em>> 註解處理多部分數據。它可以包含文本和二進制數據,但只能與 POST 動詞一起使用。