URL 矩阵参数对比查询参数

我想知道在我的 URL 中是否使用矩阵或查询参数。我发现一个更老的相关讨论,不过我并不满意。

例子

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

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

但也有缺点:

  • 只有像jax - rs这样的少数框架支持矩阵参数
  • 当浏览器通过GET提交表单时,这些参数就变成了查询参数。因此,对于同一个任务,它最终有两种参数。为了不让REST服务的用户感到困惑,并限制服务开发人员的工作,在这方面总是使用查询参数会更容易。

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

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

83840 次浏览

重要的区别是矩阵参数应用于特定的路径元素,而查询参数应用于整个请求。当对多级资源和子资源进行复杂的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这样的框架时,所有查询参数都将显示在每个资源处理程序中,从而导致潜在的冲突和混乱。

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

——太重要了,不能放在评论区

我不确定矩阵url有什么大不了的。根据TBL所写的w3c设计文章,它只是一个设计想法,并明确表示它不是web的一个功能。使用它时不会实现相对url之类的东西。如果你想使用它,那很好;没有标准的方法来使用它,因为它不是标准的。

——史蒂夫城堡

因此,简单地说,如果出于业务目的需要RS,最好使用请求参数。

除了蒂姆·西尔维斯特的回答之外,我还想提供一个如何用JAX-RS处理矩阵参数的示例。

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

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

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

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

    < em > < / em >反应

    green
    

    但就像Javadoc国家一样

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

    ... 是什么把我们带到第2点

  2. < p > 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;
    }
    

    < em > < / em >反应

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

    由于矩阵参数是作为MultivaluedMap提供的,您可以通过

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

    或者你只需要第一个

    String name = matrixParameters.getFirst("name");
    
  3. Get all matrix parameters as one method parameter

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

    使用List<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();
    }
    

    < em > < / em >反应

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]