URL矩阵参数与请求参数

dea*_*mon 170 parameters rest url http jax-rs

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

例子

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

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

但也有缺点:

  • 只有少数像JAX-RS这样的框架支持矩阵参数
  • 当浏览器通过GET提交表单时,params成为查询参数.因此它最终会出现两种相同任务的参数.为了不混淆REST服务的用户并限制服务开发人员的工作量,在这个领域中使用始终查询参数会更容易.

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

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

Tim*_*ter 204

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

http://example.com/res/categories;name=foo/objects;name=green/?page=1
Run Code Online (Sandbox Code Playgroud)

这真的归结为命名空间.如果仅使用查询参数,则最终会使用"category_name"和"object_name"等参数,并且您将失去请求中参数的位置所添加的清晰度.此外,当使用像JAX-RS这样的框架时,所有查询参数都会显示在每个资源处理程序中,从而导致潜在的冲突和混淆.

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

  • 虽然矩阵参数确实可以在任何路径段中指定,但是例如JAX-RS不会将它们与使用@MatrixParam注入时附加到的路径段相关联.根据"使用JAX-RS 2.0的Restful Java",诸如"GET/mercedes/e55; color = black/2006/interior; color = tan"之类的请求将具有颜色矩阵参数的模糊定义.虽然看起来如果你单独处理每个PathSegment,你可以弄明白......这比你指定categoryName = foo; objectName = green更有用但更多的工作要做到这一点. (8认同)
  • `?`启动请求的查询参数部分.查询参数是最常见的URL参数类型,而不是矩阵参数.问号前面的斜杠确保查询参数"page"不会遇到斜杠之前的矩阵参数.我想如果没有矩阵参数附加到`categories`,查询参数可以附加没有像这样的斜杠:`http://example.com/res/categories?page = 1` (7认同)
  • 哇超级有趣,从未听说过参数局部性,即使已经20年的网络开发!+1 (7认同)
  • 无关紧要:`/?`部分代表资源? (2认同)

Ren*_*ink 12

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

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

    http://localhost:8080/res/categories/objects;name=green
    
    Run Code Online (Sandbox Code Playgroud)

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

    @GET
    @Path("categories/objects")
    public String objects(@MatrixParam("name") String objectName) {
      return objectName;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    响应

    green
    
    Run Code Online (Sandbox Code Playgroud)

    但就像Javadoc所说的那样

    请注意,@MatrixParam注释值是指矩阵参数的名称,该参数位于注入了矩阵参数值的Path-annotated Java结构的最后匹配路径段中.

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

  2. URL中间的Matrix参数

    http://localhost:8080/res/categories;name=foo/objects;name=green
    
    Run Code Online (Sandbox Code Playgroud)

    您可以使用路径变量和任何地方访问矩阵参数@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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    响应

    object green, path:categories, matrixParams:[name=foo]
    
    Run Code Online (Sandbox Code Playgroud)

    由于矩阵参数是作为一个提供的,因此MultivaluedMap您可以访问每个参数

    List<String> names = matrixParameters.get("name");
    
    Run Code Online (Sandbox Code Playgroud)

    或者如果你只需要第一个

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

    http://localhost:8080/res/categories;name=foo/objects;name=green//attributes;name=size
    
    Run Code Online (Sandbox Code Playgroud)

    用a 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();
    }
    
    Run Code Online (Sandbox Code Playgroud)

    响应

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]
    
    Run Code Online (Sandbox Code Playgroud)


Aje*_*nga 10

- 降级评论部分非常重要.--

我不确定矩阵URL的重要性.根据TBL写的w3c设计文章,它只是一个设计理念,并明确指出它不是网络的一个特征.使用它时,没有实现相对URL之类的东西.如果你想使用它,那很好; 没有标准的方法可以使用它,因为它不是标准的. - 史蒂夫波默罗伊

如此简短的回答是,如果您出于商业目的需要RS,最好使用请求参数.

  • 我想每个认为这是非标准的人都不熟悉uri模板规范吗?在路径参数中编码复杂对象是uri模板的一个非常有用的功能; 仅仅因为大多数人不知道或使用它并不意味着角度开发者为你的生活注入无用的复杂性是一些邪恶的阴谋. (7认同)
  • 有人告诉Angular 2开发人员,他们认为他们是如此独特,他们需要实现这一点! (5认同)
  • @MattPileggi我也是因为Angular 2而读这篇文章.几乎Angular 2的每个方面都是高度专业化的,非常规的,与现有的使用模式不一致.目前尚未证实这增加了缓解价值. (2认同)
  • 噗——“&lt;我直到现在才知道存在的东西&gt;是_非标准_,因此保留了我的无知的可接受性”。TBL 决定对一个想法做什么或不做什么在很大程度上是无关紧要的。这不是 2001 年 Web 的一个功能。Web 的“功能”是客户端和服务器实现者选择的功能。如果 Angular 支持矩阵参数并且 JAX-RS 支持它们,并且这些是您选择的实现工具,那么请继续使用有效的工具。 (2认同)