Matrix Variables

RFC 3986 讨论了路径段中的名称-值对。在 Spring WebFlux 中,我们根据 Tim Berners-Lee 的 “old post” 将它们称为 “matrix variables”,但也可以称为 URI 路径参数。

矩阵变量可以出现在任何路径段中,每个变量用分号分隔,而多个值用逗号分隔,例如“/cars;color=red,green;year=2012”。也可以通过重复的变量名指定多个值,例如“color=red;color=green;color=blue”。

与 Spring MVC 不同,在 WebFlux 中,URL 中是否存在矩阵变量不会影响请求映射。换句话说,您不需要使用 URI 变量来掩码变量内容。也就是说,如果您想从控制器方法访问矩阵变量,则需要将 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
}
@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]
}