Jersey RESTful服务:资源和响应
我看到很多基于泽西岛的Web服务由1个以上的WebResources
组成,这些WebResources
有1个以上的端点/方法,如下所示:
package com.myws.fizz; public class FizzResource { @GET @Path("/fizz/{id}") public Response getFizzById(@PathParam("id") Long id) { // ...etc. } @GET @Path("/fizz") public Fizz getFizzByFoo(Foo foo) { // ...etc. } } package com.myws.buzz; public class BuzzResource { @POST @Path("/buzz") public Response createBuzz(Buzz buzz) { // ...etc. } }
- 我对泽西岛认为的“资源”感到困惑。 “资源”和数据库之间是否存在关系? 一张桌子? 一个POJO?
- 你何时返回一个
Response
与一个POJO? 看看我上面的2个getFizz
方法。 我何时返回Fizz
,何时返回Response
?
术语“资源”并不仅仅是泽西岛术语,因为它是一个REST术语。 在处理REST时,我们有资源和表示 。 资源可以是任何东西,在这种情况下,它是位于服务器上的某个对象,具有URL位置。 当客户端请求资源时,我们会发回它的表示。 你问:
“资源”和数据库之间是否存在关系? 一张桌子? 一个POJO?
它可能是一个数据库(这是一件事)。 我们可以简单地将其表示为具有数据库名称的JSON对象。 它也可能是一张桌子(这是一件事)。 我们可以将它表示为具有名称和列名称的JSON对象。 它可以是表中的一行,我们可以使用JSON对象来表示该行,其中列名称作为键,行值作为JSON值。 它可以是一个网页,一个图像,等等。 所以希望你明白资源可以是任何东西 。 我们发回的是它的代表。
但术语资源不仅限于将某些内容返回给客户端请求。 客户端还可以向我们发送资源的表示,例如创建新资源(POST)或更改现有资源(PUT)。 客户端可以在我们的数据库中向我们发送行(资源)的JSON表示。
你何时返回一个
Response
与一个POJO? 看看我上面的2个getFizz
方法。 我何时返回Fizz
,何时返回Response
?
返回Response
允许您微调Response
。 当客户提出请求时,他们总是会收到回复。 响应具有标头和实体主体。 当资源方法的返回类型是Fizz
,您说实体主体类型将是Fizz
类型。 当方法返回时,实际发生的事情是Fizz
对象不是直接返回给请求客户端,而是全部。 在幕后,它被包含在一个Response
,并被发送回客户端。 框架将设置合适的标头。
因此,无论我们决定返回Response
还是Fizz
,它都会被包含在Response
。 就像我说的,当我们返回一个Response
,它允许我们微调Response
,添加我们自己的头文件,状态代码等。 例如,假设有人POST
。 你可以做点什么
@POST @Path("/buzz") @Produces(...) public Response createBuzz(Buzz buzz, @Context UriInfo uriInfo) { int buzzID = // create buzz and get the resource id UriBuilder builder = uriInfo.getAbsolutePathBuilder(); builder.path(Integer.toString(buzzId)); // concatenate the id. return Response.created(builder.build()).build(); }
基本上它的作用是创建资源,比如在数据库中,我们得到一个返回id。 我们可以使用id连接到id的URI,这将是新的资源位置。 就Response
, .created(...)
表示状态代码应为201 Created
,并且我们传递给created
方法的值是新创建的资源的位置。 此位置将设置为响应中的Location
标头。 因此,我们可以说POST请求的路径是http://blah.com/buzz
。 我们要发回的是http://blah.com/buzz/100
,其中100
是buzzId
,这个完整的URL是我们如何访问buzz资源,如果用GET请求者访问一个用@GET注释的资源方法@GET @PATH("/buzz/{id}")
就GET
,通过Response
,我们可以做到
Fizz newFizz = fizzService.getFizz(); return Response.ok(newFizz).build(); // sends the Fizz as the entity body
这与从方法返回newFizz
实际上并没有多大区别,因为我们没有对Response
执行任何特殊操作。 我们只是说状态代码应该是200 OK
并附加实体主体。 这是成功的GET请求通常会发生的情况。 因此,如果我们只是返回Fizz
而不是Response
,则在成功获取GET的情况下,框架将隐式附加200 OK状态。
就个人而言,由于微调因素,我更愿意回复Responses
。