1.概述

URI规范RFC 3986将URI路径参数定义为名称-值对。矩阵变量是Spring创造的术语,是传递和解析URI路径参数的替代实现。

为了简化带有大量参数的请求,Spring MVC 3.2开始提供了对矩阵变量的支持。

在本文中,我们将展示如何简化复杂的GET请求,在请求URI的不同路径段内使用变量或可选路径参数。

2.启用矩阵变量

默认情况下,矩阵变量绑定到参数的功能是禁止的。

需要自己启用Spring MVC矩阵变量。

让我们从配置开始:

public class WebConfig implements WebMvcConfigurer {
		@Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // 关闭后缀模式匹配
        configurer.setUseSuffixPatternMatch(false);
        // 矩阵变量绑定参数
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setRemoveSemicolonContent(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

3. 如何使用矩阵变量

矩阵变量可以出现在路径的任何部分,并且用等号(“ =”)给出键值,而用分号(';')分隔每个矩阵变量。

在同一路径上,我们还可以使用字符逗号(',')重复相同的变量名称或分隔不同的值。

我们以图书检索来举例说明:

每本书都有作者,出版时间等信息,我们可以按该属性进行搜索。

以下请求可用于搜索:

http://localhost:8080/book/author=a,b,c

或者

http://localhost:8080/book/author=a;author=b;author=c

当我们想在Spring MVC中引用这些变量时,就需要使用注解@MatrixVariable了。

4.定义矩阵变量属性

我们可以为矩阵变量指定必需或可选属性。默认为必须。

在以下示例中,author是必需的,因此它必须包含在我们的路径中,如下所示:

http://localhost:8080/mv/author=123

请求将通过以下方法处理:

@RequestMapping(value = "/mv/{author}", method = RequestMethod.GET)
@ResponseBody
public String dotPathVariable2(@MatrixVariable(required = true) String author) {
  return String.format("author: %s ", author);
}

我们来测试一下:

# curl http://localhost:8080/mv/author=123
author: 123 %

矩阵变量成功的绑定到author参数上。

5.补充参数

矩阵变量可以补充路径变量。

例如,我们正在搜索书的名字,但是我们还可以包括书的作者。

搜索请求应如下所示:

http://localhost:8080/mv2/thinkinjava;author=123

请求将通过以下方法处理:

@RequestMapping(value = "/mv2/{name}", method = RequestMethod.GET)
@ResponseBody
public String dotPathVariable2(
  @PathVariable String name,
  @MatrixVariable String author) {
  return String.format("book: %s ;author: %s ", name, author);
}

测试一下:

# curl http://localhost:8080/mv2/thinkinjava;author=pei
book: thinkinjava ;author: pei %

###6.绑定所有矩阵变量

有时候,我们可能需要获取路径上所有可用的变量,可以将它们绑定到Map:

http://localhost:8080/mv3/author=pei;year=2019;name=ripjava;id=01214

请求将通过以下方法处理:

@RequestMapping(value = "/mv3/{book}", method = RequestMethod.GET)
@ResponseBody
public String dotPathVariable3(
  @MatrixVariable Map<String, String> matrixVars) {
  return String.format("author:%s; year:%s; name:%s; id:%s",
                       matrixVars.get("author"),
                       matrixVars.get("year"),
                       matrixVars.get("name"),
                       matrixVars.get("id") );
}

测试一下:

# curl http://localhost:8080/mv3/author=pei;year=2019;name=ripjava;id=01214
author:pei; year:2019; name:ripjava; id:01214%

7. 局部绑定矩阵变量

矩阵变量可以多种不同方式使用。例如,我们可以从每个路径段获取每个变量。

考虑以下请求:

http://localhost:8080/mv4/store/name=tianya;address=lalalaid/book/name=java;author=pei

如果我们只是想知道矩阵变量名中的store段,那么,我们应该为参数如下输入使用:

@RequestMapping(value = "/mv4/store/{store}/book/{book}", method = RequestMethod.GET)
@ResponseBody
public String dotPathVariable4(
  @MatrixVariable(value="name", pathVar="store") String storeName ) {
  return String.format("store name: %s", storeName);
}

测试一下:

# curl http://localhost:8080/mv4/store/name=tianya;address=lalalaid/book/name=java;author=pei

store name: tianya%

8.结论

本文说明了使用矩阵变量的各种方式, 了解矩阵变量如何处理过于复杂的请求或帮助我们添加更多参数来界定搜索范围。

与往常一样,可以在GitHub上找到示例实现。