“资源”一词不仅仅是一个 Jersey 术语,它是一个 REST 术语。在处理 REST 时,我们有 Resources 和 Representations。资源可以是任何东西,在这种情况下,它是位于服务器上的某个对象,具有 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 将 URI 连接到 id,这将是新的资源位置。对于Response,.created(...) 是说status code 应该是201 Created,我们传递给created 方法的值就是新创建资源的位置。此位置将设置为响应中的 Location 标头。假设 POST 请求的路径是http://blah.com/buzz。我们要发回的是http://blah.com/buzz/100,其中100 是buzzId,而这个完整的URL 是我们将如何访问buzz 资源的方式>
就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,因为微调因素。