Matrix Variables

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

RFC 3986 discusses name-value pairs in path segments. In Spring MVC, we refer to those as “matrix variables” based on an “old post” by Tim Berners-Lee, but they can be also be referred to as URI path parameters.

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

Matrix variables can appear in any path segment, with each variable separated by a semicolon and multiple values separated by comma (for example, /cars;color=red,green;year=2012). Multiple values can also be specified through repeated variable names (for example, color=red;color=green;color=blue).

如果某个 URL 预计包含矩阵变量,则控制器方法的请求映射必须使用 URI 变量来屏蔽该变量内容,并确保无论矩阵变量的顺序和存在情况如何,都能成功匹配请求。以下示例使用矩阵变量:

If a URL is expected to contain matrix variables, the request mapping for a controller method must use a URI variable to mask that variable content and ensure the request can be matched successfully independent of matrix variable order and presence. The following example uses a matrix variable:

  • 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
}

由于所有路径段都可能包含矩阵变量,因此有时你可能需要消除歧义,以确定矩阵变量预期在哪个路径变量中。以下示例演示了如何执行此操作:

Given that all path segments may contain matrix variables, you may sometimes need to disambiguate which path variable the matrix variable is expected to be in. The following example shows how to do so:

  • 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
}

矩阵变量可以定义为可选变量,并可以指定默认值,如下例所示:

A matrix variable may be defined as optional and a default value specified, as the following example shows:

  • 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,如下例所示:

To get all matrix variables, you can use a MultiValueMap, as the following example shows:

  • 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 配置中,您需要通过 Path Matching 使用 UrlPathHelper 设置一个 removeSemicolonContent=false。在 MVC XML 名称空间中,您可以设置 <mvc:annotation-driven enable-matrix-variables="true"/>

Note that you need to enable the use of matrix variables. In the MVC Java configuration, you need to set a UrlPathHelper with removeSemicolonContent=false through Path Matching. In the MVC XML namespace, you can set <mvc:annotation-driven enable-matrix-variables="true"/>.