1. 簡介
Jersey 是一個功能齊全的開源框架,用於使用 Java 開發 Web 服務和客户端。 通過使用 Jersey,我們可以創建支持 HTTP 功能的強大 Web 應用程序。
在本文中,我們將探討 Jersey 的兩個特定功能: @FormDataParam 和 @FormParam 註解。 儘管這兩個註解在本質上相似,但它們之間存在顯著差異,正如我們將在下面看到。
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)
{
// 處理表單數據
}
請注意,我們為表單中的每個字段使用該註解。 這一點在字段數量或類型如何,表單有多少或多少,都適用。 通過使用 @FormParam 註解,Jersey 將每個字段的值綁定到相應的參數中。
在實踐中,表單編碼數據對應於 MIME 類型 application/x-www-form-urlencoded。 在瀏覽器和我們的服務之間傳輸的數據如下所示:
first_name=john&last_name=smith&age=42
這種方法的優勢在於數據易於處理,因為它只涉及文本,不涉及二進制數據。 此外,這種方法可以使用HTTP GET 動詞,因為字符串可以作為URL查詢參數傳遞。 但是,通過URL傳遞表單數據時,我們應該小心,因為其中可能包含敏感數據。
4. 使用 @FormDataParam
@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>
請注意,我們現在在表單元素中指定了 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)
{
// 處理表單數據
}
請注意,每個表單字段現在都使用了 @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--
POST 動詞與此類型一起使用。 這是因為二進制數據無法編碼並傳遞到 URL 字符串中。 其次,有效負載的大小比普通 form-encoded 數據大得多。 如上例所示,用於定義分隔符和標題所需的額外文本會增加大量大小。
5. 結論
在本文中,我們探討了 Jersey 庫中兩種不同的註解:@FormParam 和 @FormDataParam。 這兩種註解都用於處理應用程序中的表單數據,但正如我們所見,它們具有非常不同的目的。
@FormParam 更適合用於發送表單編碼數據。它可以使用 GET 或 POST 動詞,但只能包含文本字段。另一方面,@FormDataParam 註解處理多部分數據。它可以包含文本和二進制數據,但只能與 POST 動詞一起使用。