什么时候使用@QueryParam和@PathParam

我不是在问这里已经问过的问题: @PathParam和@QueryParam有什么区别 < / p >

这是一个“最佳实践”或惯例问题。

什么时候使用@PathParam@QueryParam

我能想到的是,这个决定可能是用这两者来区分信息模式。让我在下面说明我的LTPO -不完美的观察。

PathParam的使用可以保留在信息类别中,这将很好地归入信息树的一个分支。PathParam可以用于下钻到实体类层次结构。

然而,QueryParam可以保留用于指定属性以定位类的实例。

例如,

  • /Vehicle/Car?registration=123
  • /House/Colonial?region=newengland

/category?instance

@GET
@Path("/employee/{dept}")
Patient getEmployee(@PathParam("dept")Long dept, @QueryParam("id")Long id) ;

vs /category/instance

@GET
@Path("/employee/{dept}/{id}")
Patient getEmployee(@PathParam("dept")Long dept, @PathParam("id")Long id) ;

vs ?category+instance

@GET
@Path("/employee")
Patient getEmployee(@QueryParam("dept")Long dept, @QueryParam("id")Long id) ;

我不认为这样做有一个标准的惯例。是吗?然而,我想知道人们如何使用PathParam和QueryParam来区分他们的信息,就像我上面举例的那样。我也很想知道这种做法背后的原因。

514868 次浏览

我个人使用的方法是“如果对用户来说书签包含这些参数的url是有意义的,那么使用PathParam”。

例如,如果用户配置文件的URL包含一些配置文件id参数,因为这可以被用户收藏和/或通过电子邮件发送,我将包括该配置文件id作为路径参数。另外,另一个需要考虑的因素是,包含路径参数的URL所表示的页面不会改变——用户将建立他/她的配置文件,保存它,然后不太可能从那里改变太多;这意味着网络爬虫/搜索引擎/浏览器等可以根据路径很好地缓存这个页面。

如果在URL中传递的参数可能会改变页面布局/内容,那么我将使用它作为查询参数。例如,如果配置文件URL支持指定是否显示用户电子邮件的参数,我会将其视为查询参数。(我知道,有争议的是,你可以说&noemail=1或任何参数都可以用作路径参数,并生成两个单独的页面——一个上面有电子邮件,一个没有——但逻辑上不是这样的:它仍然是相同的页面,显示或不显示某些属性。

希望这能有所帮助——我很感激这个解释可能有点模糊:)

可以使用查询参数进行过滤,使用路径参数进行分组。下面的链接有关于这个何时使用pathParams或QueryParams的很好的信息

这就是我的工作。

如果存在基于id检索记录的场景,例如您需要获取id为15的员工的详细信息,那么您可以使用@PathParam资源。

GET /employee/{id}

如果需要获得所有员工的详细信息,但每次只需要10个,则可以使用query param

GET /employee?start=1&size=10

这表示,起始雇员id 1获得10条记录。

总之,使用@PathParam进行基于id的检索。用户@QueryParam用于过滤器,或者如果你有任何用户可以传递的固定选项列表。

REST本身可能不是一个标准,但是阅读一般的REST文档和博客文章应该会给你一些指导,让你更好地构造API url。大多数其他api倾向于在路径中只有资源名称和资源id。如:

/departments/{dept}/employees/{id}

一些REST api使用查询字符串进行过滤、分页和排序,但由于REST不是一个严格的标准,我建议检查一些REST api,如githubstackoverflow,看看哪些api适合你的用例。

我建议在路径中放入任何必需的参数,而任何可选参数都应该是查询字符串参数。当尝试编写匹配不同组合的URL处理程序时,在路径中放置可选参数最终会变得非常混乱。

我认为,如果参数标识一个特定的实体,您应该使用路径变量。例如,为了获得我所请求的博客上的所有帖子

GET: myserver.com/myblog/posts

要获得id = 123的职位,我会请求

GET: myserver.com/myblog/posts/123

但要过滤我的帖子列表,并获得2013年1月1日以来的所有帖子,我会要求

GET: myserver.com/myblog/posts?since=2013-01-01

在第一个例子中,“posts”标识了一个特定的实体(博客文章的整个集合)。在第二个例子中,“123”也表示一个特定的实体(一篇博客文章)。但是在最后一个例子中,参数“since=2013-01-01”是一个过滤posts集合的请求,而不是一个特定的实体。分页和排序是另一个很好的例子。

GET: myserver.com/myblog/posts?page=2&order=backward

希望这能有所帮助。: -)

正如席恩所指出的,REST不是一个标准。然而,如果你想要实现一个基于标准的URI约定,你可以考虑oData URI约定。版本4已经是被批准为OASIS标准,并且存在用于各种语言的oData库,包括通过Apache吻浣熊的Java。不要因为它是微软的衍生而让你望而却步,因为它是也获得了其他行业参与者的支持,其中包括红帽,Citrix, IBM,黑莓,Drupal, Netflix Facebook和SAP

更多的采用者在这里列出了

原因其实很简单。当使用查询参数时,你可以输入字符,如“/”,你的客户端不需要对它们进行html编码。还有其他原因,但这只是一个简单的例子。至于何时使用路径变量。我想说的是,当你处理id或者路径变量是一个查询的方向时。

我给了一个例子来理解我们什么时候使用@Queryparam@pathparam

例如,我正在使用的一个资源是carResource

如果你想让你的资源方法的输入是强制性的,那么使用参数类型@pathaparam,如果你的资源方法的输入应该是可选的,那么保持参数类型@QueryParam参数

@Path("/car")
class CarResource
{
@Get
@produces("text/plain")
@Path("/search/{carmodel}")
public String getCarSearch(@PathParam("carmodel")String model,@QueryParam("carcolor")String color) {
//logic for getting cars based on carmodel and color
-----
return cars
}
}

为这个资源传递请求

req uri ://address:2020/carWeb/car/search/swift?carcolor=red

如果你给出这样的要求,资源将给出基于汽车的型号和颜色

 req uri://address:2020/carWeb/car/search/swift

如果你给出这样的要求,资源方法将只显示基于快速模型的汽车

req://address:2020/carWeb/car/search?carcolor=red

如果你这样给出,我们会得到ResourceNotFound异常,因为在car资源类中,我将carmodel声明为@pathPram,这意味着你必须并且应该将carmodel作为reQ uri,否则它将不会将reQ传递给resource,但如果你不传递颜色,它也会将reQ传递给resource,为什么呢?因为颜色是@quetyParam,它在reQ中是可选的。

这是个很有趣的问题。

你可以同时使用它们,关于这个主题没有任何严格的规则,但是使用URI路径变量有一些优点:

    <李> 缓存: 大多数互联网上的web缓存服务不缓存GET请求时,他们包含查询参数。 他们这样做是因为有很多RPC系统使用GET请求来更改服务器中的数据(失败!!)Get必须是一个安全的方法)

但是如果使用路径变量,所有这些服务都可以缓存GET请求。

    <李> 层次结构: 路径变量可以表示层次结构: 李/城市/街道/ < / >

它为用户提供了关于数据结构的更多信息。

但如果你的数据没有任何层次关系,你仍然可以使用Path变量,使用逗号或分号:

/城市/经度,纬度

作为规则,当参数的顺序重要时使用逗号,当顺序不重要时使用分号:

/ IconGenerator /红色,蓝色,绿色

除了这些原因之外,在某些情况下,使用查询字符串变量是非常常见的:

  • 当您需要浏览器自动将HTML表单变量放入URI时
  • 当你处理算法的时候。例如谷歌引擎使用查询字符串:

http:// www.google.com/search ? q =休息

总而言之,没有任何强烈的理由使用这种方法,但只要可以,就使用URI变量。

  1. @QueryParam可以方便地与默认值注释一起使用,以便在没有传递查询参数时避免空指针异常。

当你想解析来自GET请求的查询参数时,你可以简单地为处理GET请求的方法定义相应的参数,并使用@QueryParam注释来注释它们

  1. @PathParam提取URI值并匹配到@Path。从而得到输入参数。 2.1 @PathParam可以不止一个,并且被设置为方法参数

    @Path("/rest")
    public class Abc {
    
    
    @GET
    @Path("/msg/{p0}/{p1}")
    @Produces("text/plain")
    public String add(@PathParam("p0") Integer param1, @PathParam("p1")  Integer param2 )
    {
    return String.valueOf(param1+param2);
    }
    }
    

In the above example,
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0 matches param1 and p1 matches param2. So for the URI
http://localhost:8080/Restr/rest/msg/4/6,
we get the result 10.

In REST Service, JAX-RS provides @QueryParam and @FormParam both for accepting data from HTTP request. An HTTP form can be submitted by different methods like GET and POST.

@QueryParam : Accepts GET request and reads data from query string.

@FormParam: Accepts POST request and fetches data from HTML form or any request of the media

来自维基百科:统一资源定位器

一个路径,其中包含数据通常以等级形式组织,它显示为由斜杠分隔的段序列。

可选查询,用问号(?)与前一部分分隔,包含非层次数据的查询字符串。

-根据URL的概念设计,我们可以为分层数据/指令/定位器组件实现一个PathParam,或者当数据不是分层时实现一个QueryParam。这是有意义的,因为路径是自然有序的,而查询包含的变量可能是任意有序的(无序的变量/值对)。

之前的一位评论者写道,

我认为,如果参数标识一个特定的实体,您应该使用路径变量。

另一个写道:

使用@PathParam基于id进行检索。用户@QueryParam用于过滤器,或者如果你有任何用户可以传递的固定选项列表。

另一个,

我建议在路径中放入任何必需的参数,而任何可选参数都应该是查询字符串参数。

-但是,可以实现一个灵活的、非等级的系统来识别特定的实体!一个SQL表上可能有多个唯一索引,并且允许使用包含唯一索引的字段的任何组合来标识实体!不同的组合(可能顺序也不同)可能用于来自各种相关实体(引用者)的链接。在这种情况下,我们可能正在处理用于标识单个实体的非层次数据——或者在其他情况下,可能只指定某些变量/字段——唯一索引的某些组件——并检索记录列表/集。在这种情况下,将url实现为QueryParams可能会更容易、更符合逻辑和合理!

一个长十六进制字符串是否会稀释/减少路径其余部分的关键字的值?它可能值得考虑在路径或查询中放置变量/值的潜在SEO影响,以及我们是否希望用户能够通过编辑地址栏的内容来遍历/探索url的层次结构的人机界面含义。我的404 Not Found页面使用SSI变量自动重定向坏的url到他们的父!搜索机器人也可以遍历路径层次结构。 另一方面,就我个人而言,当我在社交媒体上分享URL时,我会手动删除任何私有的唯一标识符——通常是通过截断URL中的查询,只留下路径:在这种情况下,在路径中而不是在查询中放置唯一标识符会有一些实用性。我们是否希望将路径组件用作粗糙的用户界面,这可能取决于数据/组件是否适合人类阅读。人类可读性的问题在某种程度上与层次结构的问题有关:通常,可以表示为人类可读的关键字的数据也是有层次的;而层次数据通常可以表示为人类可读的关键字。(搜索引擎本身可以被定义为将url作为用户界面来使用。)关键字或指令的层次结构可能不是严格有序的,但它们通常足够接近,以至于我们可以覆盖路径中的其他情况,并且将一个选项标记为“规范”情况.

.

对于每个请求的URL,我们可能会回答几种基本的问题:

  1. 我们要求/提供什么样的记录/东西?
  2. 我们对哪一个感兴趣?
  3. 我们希望如何呈现信息/记录?
Q1几乎可以肯定最好由路径或PathParams覆盖。 Q3(可能通过一组任意顺序的可选参数和默认值进行控制);几乎可以肯定QueryParams是最好的。 Q2:这取决于…

您可以同时支持查询参数和路径参数,例如,在资源聚合的情况下——当子资源的集合本身有意义时。

/departments/{id}/employees
/employees?dept=id

查询参数可支持分层和非分层子集设置;路径参数仅分级。

资源可以显示多个层次结构。如果要查询跨层次边界的广泛子集合,则支持短路径。

/inventory?make=toyota&model=corolla
/inventory?year=2014

使用查询参数组合正交层次结构。

/inventory/makes/toyota/models/corolla?year=2014
/inventory/years/2014?make=toyota&model=corolla
/inventory?make=toyota&model=corolla&year=2014

在组合的情况下只使用路径参数——当一个资源脱离了它的父元素就没有意义了,而且所有子元素的全局集合本身并不是一个有用的资源。

/words/{id}/definitions
/definitions?word=id   // not useful

简而言之,

@Pathparam适用于通过资源和查询字符串传递的值

  • /user/1
  • /user?id=1

@Queryparam适用于仅传递查询字符串的值

  • /user?id=1

在讨论QueryParam &PathParam。让我们首先了解URL &它的组件。URL由端点+资源+ queryParam/ PathParam组成。

例如,

URL: https://app.orderservice.com/order?order=12345678

URL: https://app.orderservice.com/orders/12345678

在哪里

端点:https://app.orderservice.com

资源:订单

queryParam:订单= 12345678

PathParam: 12345678

@QueryParam:

当需求是基于特定的条件/标准筛选请求时,使用QueryParam。标准是用?URL中资源的后面。可以在queryParam中使用&的象征。

例如:

https://app.orderservice.com/orders?order=12345678 & customername=X

@PathParam:

当需要基于guid/id选择特定的顺序时,使用PathParam。PathParam是URL中资源的一部分。

例如:

https://app.orderservice.com/orders/12345678

对于资源名称和id,我使用@PathParams。对于可选变量,我使用@QueryParams

根据我的理解:

  1. 使用@PathParam -当它是一个强制性的项目,如Id

    获得/气球/ {id}

  2. 使用@QueryParam -当你有确切的资源,但需要过滤一些可选的特征,如颜色,大小等。

    得到/气球/ 123 ?颜色= red&大小=

路径参数- 路径参数是URL路径中的一个变量,帮助指向一些特定的资源

Example - https://sitename.com/questions/115

这里,如果115是一个路径参数,它可以用其他有效的数字来改变,以获取/指向同一应用程序上的其他一些资源。

查询参数- 查询参数是URL路径中的变量,用于从列表中过滤某些特定的资源

Example - https://sitename.com/questions/115?qp1=val1&qp2=val2&qp3=val3

其中qp1、qp2和qp3为查询变量,其值分别为val1、val2和val3。在获取/保存数据时,这些可以用作过滤器。查询变量总是在URL中以问号(?)结尾。

我喜欢以下几点:

@PathParam

当需要参数时,例如ID, productNo .

GET /user/details/{ID}
GET /products/{company}/{productNo}

@QueryParam

当你需要传递可选参数,如过滤器,在线状态和他们可以是null

GET /user/list?country=USA&status=online
GET /products/list?sort=ASC

同时使用时

GET /products/{company}/list?sort=ASC