知識庫 / Spring RSS 訂閱

處理 URL 編碼的表單數據在 Spring REST 中

REST,Spring
HongKong
5
03:49 AM · Dec 06 ,2025

1. 概述

對於最終用户而言,表單提交的過程就像輸入數據並點擊提交按鈕一樣便捷。然而,從工程角度來看,它需要一個編碼機制,以可靠地將客户端的數據發送到服務器端進行後端處理。

在本教程的範圍內,我們將重點創建發送其數據為 <em >application/x-www-form-urlencoded</em > 內容類型的表單,在 Spring Web 應用程序中。

2. 表單數據編碼

使用最常見的 HTTP 方法提交表單數據是 POST。然而,對於冪等表單提交,我們也可以使用 HTTP GET 方法。並且,通過 <a href="https://www.w3.org/TR/html4/interact/forms.html#adef-method">表單的 method 屬性</a> 來指定方法。

對於使用 GET 方法的表單,整個表單數據將作為查詢字符串的一部分發送。但是,如果使用 POST 方法,則數據將作為 HTTP 請求的主體發送。

此外,在後者中,我們還可以通過表單的 <a href="https://www.w3.org/TR/html4/interact/forms.html#adef-enctype"><em >enctype 屬性</em></a > 指定數據的編碼,它可以取兩個值,即application/x-www-form-urlencoded 及其 multipart/form-data

2.1. 媒體類型 application/x-www-form-urlencoded

HTML 表單的默認值為 application/x-www-form-urlencoded,用於 enctype 屬性,因為這處理了基本用例,即數據完全為文本。然而,如果我們的用例涉及支持文件數據,則必須將其覆蓋為 multipart/form-data

基本上,它將表單數據作為鍵值對發送,鍵值對之間用 "&" 字符分隔。 此外,每個鍵和值都用 "=" 字符分隔。 進一步,所有保留字符和非字母數字字符都使用 百分編碼 進行編碼。

3. 瀏覽器表單提交

現在我們已經掌握了基本內容,接下來讓我們看看如何在 Spring Web 應用中處理 URL 編碼的表單數據,用於一個簡單的反饋提交用例

3.1. 領域模型

為了我們的反饋表單,我們需要捕獲提交者的電子郵件標識符以及評論。因此,讓我們創建一個 領域模型,在 反饋 類中:

public class Feedback {
    private String emailId;
    private String comment;
}

3.2. 創建表單

為了使用簡單的 HTML 模板創建我們的動態 Web 表單,我們需要在項目中配置 Thymeleaf。之後,我們準備添加一個 GET 端點 /feedback,該端點將為表單提供 feedback 視圖

@GetMapping(path = "/feedback")
public String getFeedbackForm(Model model) {
    Feedback feedback = new Feedback();
    model.addAttribute("feedback", feedback);
    return "feedback";
}

請注意,我們使用 反饋 作為模型屬性來捕獲用户輸入。接下來,讓我們在 創建 反饋 視圖,在 feedback.html 模板中:

<form action="#" method="post" th:action="@{/web/feedback}" th:object="${feedback}">
    <!-- form fields for feedback's submitter and comment info -->
</form>

當然,我們無需明確指定 enctype 屬性,因為它會選擇默認值 application/x-www-form-urlencoded

3.3. PRG 流程

當通過瀏覽器反饋表單接收用户輸入時,必須實施 POST/REDIRECT/GET (PRG) 提交工作流程,以避免重複提交

首先,讓我們實施 POST 端點 /web/feedback,它將作為反饋表單的動作處理程序:

@PostMapping(
  path = "/web/feedback",
  consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public String handleBrowserSubmissions(Feedback feedback) throws Exception {
    // Save feedback data
    return "redirect:/feedback/success";
}

接下來,我們可以實現重定向端點 /feedback/success</em/>,該端點處理 GET 請求:

@GetMapping("/feedback/success")
public ResponseEntity<String> getSuccess() {
    return new ResponseEntity<String>("Thank you for submitting feedback.", HttpStatus.OK);
}

為了驗證瀏覽器中表單提交工作流的功能,請訪問 localhost:8080/feedback

最後,我們還可以檢查表單數據是否以 URL 編碼的形式發送:

emailId=abc%40example.com&comment=Sample+Feedback

4. 非瀏覽器請求

在某些情況下,我們可能沒有基於瀏覽器的 HTTP 客户端。 我們的客户端可能是一個實用工具,例如 cURL 或 Postman。 在這種情況下,我們不需要 HTML Web 表單。 相反,我們可以實現一個 /feedback 端點,該端點處理 POST 請求:

@PostMapping(
  path = "/feedback",
  consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<String> handleNonBrowserSubmissions(@RequestBody Feedback feedback) throws Exception {
    // Save feedback data
    return new ResponseEntity<String>("Thank you for submitting feedback", HttpStatus.OK);
}

在沒有 HTML 表單的情況下,我們的數據流中並不一定需要實現 PRG 模式。但是,我們必須明確指定該資源接受 APPLICATION_FORM_URLENCODED_VALUE 媒體類型。

最後,我們可以使用 cURL 請求進行測試:

curl -X POST \
  http://localhost:8080/feedback \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'emailId=abc%40example.com&comment=Sample%20Feedback'

4.1. <em >FormHttpMessageConverter</em> 基礎

一個發送 <em >application/x-www-form-urlencoded</em> 數據的 HTTP 請求,必須在 <em >Content-Type</em> 頭部中指定。 內部,Spring 使用 <em ><a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/converter/FormHttpMessageConverter.html">FormHttpMessageConverter</a></em> 類來讀取此數據並將其與方法參數綁定。

當我們的方法參數類型為 <em >MultiValueMap</em> 時,我們可以使用 <em ><a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html">@RequestParam</a></em> 註解或 <em ><a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestBody.html">@RequestBody</a></em> 註解,以便將其與 HTTP 請求體正確地綁定。 這是因為 Servlet API 將查詢參數和表單數據合併到一個名為 <em >parameters</em> 的單個映射中,並且它還包括對請求體自動解析:

@PostMapping(
  path = "/feedback",
  consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<String> handleNonBrowserSubmissions(
  @RequestParam MultiValueMap<String,String> paramMap) throws Exception {
    // Save feedback data
    return new ResponseEntity<String>("Thank you for submitting feedback", HttpStatus.OK);
}

然而,對於非 MultiValueMap 類型的方法參數,例如我們的 Feedback 領域對象,我們必須僅使用 @RequestBody 註解。

5. 結論

在本教程中,我們簡要學習了 Web 表單中表單數據的編碼方式。我們還探討了如何處理 URL 編碼的數據,用於瀏覽器和非瀏覽器 HTTP 請求,並通過在 Spring Boot Web 應用中實現一個反饋表單來演示。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.