矩陣變數

RFC 3986 討論了路徑段中的名稱-值對。在 Spring MVC 中,我們根據 Tim Berners-Lee 的一篇“舊博文”將它們稱為“矩陣變數”,但它們也可以稱為 URI 路徑引數。

矩陣變數可以出現在任何路徑段中,每個變數之間用分號分隔,多個值之間用逗號分隔(例如,/cars;color=red,green;year=2012)。多個值也可以透過重複變數名來指定(例如,color=red;color=green;color=blue)。

如果 URL 預期包含矩陣變數,則控制器方法的請求對映必須使用 URI 變數來遮蔽該變數內容,並確保無論矩陣變數的順序和存在如何,請求都能成功匹配。以下示例使用了矩陣變數

  • Java

  • Kotlin

// GET /pets/42;q=11;r=22

@GetMapping("/pets/{petId}")
public void findPet(@PathVariable String petId, @MatrixVariable int q) {

	// petId == 42
	// q == 11
}
// GET /pets/42;q=11;r=22

@GetMapping("/pets/{petId}")
fun findPet(@PathVariable petId: String, @MatrixVariable q: Int) {

	// petId == 42
	// q == 11
}

鑑於所有路徑段都可能包含矩陣變數,有時可能需要消除歧義,指定矩陣變數預期在哪一個路徑變數中。以下示例展示瞭如何做到這一點

  • Java

  • Kotlin

// GET /owners/42;q=11/pets/21;q=22

@GetMapping("/owners/{ownerId}/pets/{petId}")
public void findPet(
		@MatrixVariable(name="q", pathVar="ownerId") int q1,
		@MatrixVariable(name="q", pathVar="petId") int q2) {

	// q1 == 11
	// q2 == 22
}
// GET /owners/42;q=11/pets/21;q=22

@GetMapping("/owners/{ownerId}/pets/{petId}")
fun findPet(
		@MatrixVariable(name = "q", pathVar = "ownerId") q1: Int,
		@MatrixVariable(name = "q", pathVar = "petId") q2: Int) {

	// q1 == 11
	// q2 == 22
}

矩陣變數可以定義為可選,並指定預設值,如下例所示

  • Java

  • Kotlin

// GET /pets/42

@GetMapping("/pets/{petId}")
public void findPet(@MatrixVariable(required=false, defaultValue="1") int q) {

	// q == 1
}
// GET /pets/42

@GetMapping("/pets/{petId}")
fun findPet(@MatrixVariable(required = false, defaultValue = "1") q: Int) {

	// q == 1
}

要獲取所有矩陣變數,可以使用 MultiValueMap,如下例所示

  • Java

  • Kotlin

// GET /owners/42;q=11;r=12/pets/21;q=22;s=23

@GetMapping("/owners/{ownerId}/pets/{petId}")
public void findPet(
		@MatrixVariable MultiValueMap<String, String> matrixVars,
		@MatrixVariable(pathVar="petId") MultiValueMap<String, String> petMatrixVars) {

	// matrixVars: ["q" : [11,22], "r" : 12, "s" : 23]
	// petMatrixVars: ["q" : 22, "s" : 23]
}
// GET /owners/42;q=11;r=12/pets/21;q=22;s=23

@GetMapping("/owners/{ownerId}/pets/{petId}")
fun findPet(
		@MatrixVariable matrixVars: MultiValueMap<String, String>,
		@MatrixVariable(pathVar="petId") petMatrixVars: MultiValueMap<String, String>) {

	// matrixVars: ["q" : [11,22], "r" : 12, "s" : 23]
	// petMatrixVars: ["q" : 22, "s" : 23]
}

請注意,需要啟用矩陣變數的使用。在 MVC Java 配置中,需要透過路徑匹配,使用設定了 removeSemicolonContent=falseUrlPathHelper。在 MVC XML 名稱空間中,可以設定 <mvc:annotation-driven enable-matrix-variables="true"/>