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

REST,Spring
Remote
1
08:31 AM · Dec 01 ,2025

1. 概述

對於最終用户而言,表單提交的過程非常便捷,在某種程度上也相當於直接輸入數據並點擊提交按鈕。但是,從工程角度來看,它需要一個編碼機制,以可靠地將客户端的數據發送到服務器端進行後端處理。

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

2. 表單數據編碼

提交表單最常用的 HTTP 方法是 POST。但是,對於冪等表單提交,我們也可以使用 HTTP GET 方法。並且,指定方法的途徑是通過表單的 method 屬性

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

此外,在後者的情況下,我們還可以通過表單的 enctype 屬性, 來指定數據的編碼方式,它可以取兩個值,即 application/x-www-form-urlencoded multipart/form-data.

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

HTML 表單的默認值對於 enctype 屬性application/x-www-form-urlencoded,因為這處理了基本用例,其中數據完全是文本。儘管如此,如果我們的用例涉及支持文件數據,則我們需要使用 multipart/form-data 的值來覆蓋它。

本質上,它將表單數據作為用鍵值對分隔,並用感嘆號 (&) 分隔。相應地,鍵和值用等號 (=) 分隔。此外,所有保留字符和非字母數字字符都使用 百分編碼 進行編碼。

3. 形式提交到瀏覽器

現在我們已經完成了基礎知識,讓我們看看如何處理 URL 編碼的表單數據,用於一個簡單的反饋提交用例,在 Spring Web 應用程序中。

3.1. 域模型

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

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

3.2. 創建表單

為了使用簡單的 HTML 模板來創建我們的動態 Web 表單,我們需要在項目中使用 Thymeleaf。之後,我們準備好添加一個 GET 端點/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,它提供一個 GET 請求:

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

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

feedback form web

最後,我們還可以檢查表單數據正在 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 {
    // 保存反饋數據
    return new ResponseEntity<String>("感謝您提交反饋", 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. FormHttpMessageConverter 基礎

發送 application/x-www-form-urlencoded 數據 的 HTTP 請求 必須在 Content-Type 標頭中指定此項。 內部,Spring 使用 FormHttpMessageConverter 類來讀取此數據並將其與方法參數綁定。

在我們的方法參數類型為 @RequestParam@RequestBody 類型的 경우, 我們可以使用這些註解來相應地將其與 HTTP 請求的 body 綁定。 這是因為 Servlet API 將查詢參數和表單數據組合成一個名為 parameters 的單個 map,並且它會自動解析請求 body:

@PostMapping(
  path = "/feedback",
  consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<String> handleNonBrowserSubmissions(
  @RequestParam MultiValueMap<String,String> paramMap) throws Exception {
    // 保存反饋數據
    return new ResponseEntity<String>("感謝您提交反饋", HttpStatus.OK);
}

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

5. 結論

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

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

發佈 評論

Some HTML is okay.