190

我想知道是否在我的 URL 中使用矩阵或查询参数。我发现对该主题的较早讨论并不令人满意。

例子

乍一看,矩阵参数似乎只有优点:

  • 更具可读性
  • 不需要对 XML 文档中的“&”进行编码和解码
  • 带有“?”的网址 很多情况下没有缓存;带有矩阵参数的 URL 被缓存
  • 矩阵参数可以出现在路径中的任何地方,并且不限于它的末尾
  • 矩阵参数可以有多个值:paramA=val1,val2

但也有缺点:

  • 只有像JAX-RS这样的少数框架支持矩阵参数
  • 当浏览器通过 GET 提交表单时,参数变为查询参数。因此,对于同一任务,它最终会得到两种参数。为了不混淆 REST 服务的用户并限制服务开发人员的工作量,在这方面使用始终查询参数会更容易。

由于服务的开发者可以选择支持矩阵参数的框架,剩下的唯一缺点就是浏览器会默认创建查询参数。

还有其他缺点吗?你会怎么办?

4

3 回答 3

227

重要的区别是矩阵参数适用于特定的路径元素,而查询参数适用于整个请求。这在对多个级别的资源和子资源进行复杂的 REST 样式查询时会发挥作用:

http://example.com/res/categories;name=foo/objects;name=green/?page=1

这真的归结为命名空间。

注意:这里的资源“级别”是categoriesobjects

如果只对多级 URL 使用查询参数,您最终会得到

http://example.com/res?categories_name=foo&objects_name=green&page=1

这样,您也会失去请求中参数的位置所增加的清晰度。此外,当使用像 JAX-RS 这样的框架时,所有查询参数都会显示在每个资源处理程序中,从而导致潜在的冲突和混乱。

如果您的查询只有一个“级别”,那么区别并不重要,两种类型的参数可以有效地互换,但是,查询参数通常得到更好的支持和更广泛的认可。一般来说,我会建议您坚持使用查询参数,例如 HTML 表单和简单的单级 HTTP API。

于 2011-04-09T03:25:45.983 回答
20

除了Tim Sylvester 的回答之外,我还想提供一个示例,说明如何使用JAX-RS处理矩阵参数。

  1. 最后一个资源元素的矩阵参数

    http://localhost:8080/res/categories/objects;name=green
    

    您可以使用@MatrixParam注释访问它们

    @GET
    @Path("categories/objects")
    public String objects(@MatrixParam("name") String objectName) {
      return objectName;
    }
    

    回复

    green
    

    但就像 Javadoc 状态

    请注意,@MatrixParam注释值是指矩阵参数的名称,该参数位于注入矩阵参数值的带注释的 Java 结构的最后一个匹配路径段中。

    ...是什么让我们来到第 2 点

  2. URL中间的矩阵参数

    http://localhost:8080/res/categories;name=foo/objects;name=green
    

    您可以使用路径变量和@PathParam PathSegment.

    @GET
    @Path("{categoryVar:categories}/objects")
    public String objectsByCategory(@PathParam("categoryVar") PathSegment categorySegment, 
                                    @MatrixParam("name") String objectName) {
      MultivaluedMap<String, String> matrixParameters = categorySegment.getMatrixParameters();
      String categorySegmentPath = categorySegment.getPath();
      String string = String.format("object %s, path:%s, matrixParams:%s%n", objectName,
              categorySegmentPath, matrixParameters);
      return string;
    }
    

    回复

    object green, path:categories, matrixParams:[name=foo]
    

    由于矩阵参数以 a 形式提供,因此MultivaluedMap您可以通过

    List<String> names = matrixParameters.get("name");
    

    或者如果你只需要第一个

    String name = matrixParameters.getFirst("name");
    
  3. 获取所有矩阵参数作为一个方法参数

    http://localhost:8080/res/categories;name=foo/objects;name=green//attributes;name=size
    

    使用 aList<PathSegment>来获取它们

    @GET
    @Path("all/{var:.+}")
    public String allSegments(@PathParam("var") List<PathSegment> pathSegments) {
      StringBuilder sb =  new StringBuilder();
    
      for (PathSegment pathSegment : pathSegments) {
        sb.append("path: ");
        sb.append(pathSegment.getPath());
        sb.append(", matrix parameters ");
        sb.append(pathSegment.getMatrixParameters());
        sb.append("<br/>");
      }
    
      return sb.toString();
    }
    

    回复

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]
    
于 2018-01-25T07:43:29.617 回答
12

--太重要了,不能放到评论区。--

我不确定矩阵 URL 有什么大不了的。根据 TBL 写的 w3c 设计文章,这只是一个设计理念,并明确指出它不是 Web 的功能。使用它时没有实现诸如相对 URL 之类的东西。如果您想使用它,那很好;只是没有标准的方式来使用它,因为它不是标准。

——史蒂夫·波默罗伊

所以简短的回答是,如果您出于业务目的需要 RS,最好使用请求参数。

于 2015-09-07T15:39:53.447 回答