我从REST开始,我有一些问题:
- 控制器必须返回什么类型?通常,我问我的 Rest
@Controller
是否必须按原样返回Item
对象或将其封装在ResponseEntity
中以指定 http-status-code。 - 如果给定项目不存在,则在特定项目("/items/2")上的 GET 方法中使用什么 http 状态代码:
HttpMediaStatus.OK
(200) 和空返回或HttpStatus.NO_CONTENT
(204) 和空返回?
第二部分:我看到可以在WS方法上指定@Produces
和@Consumes
,但是有什么用呢?我的应用程序和方法如此工作,为什么要指定MediaType.APPLICATION_JSON_VALUE
?Spring/SpringBoot 不会自动将Item
或ResponseEntity
转换为 json 吗?
上下文:使用 Spring Boot、hibernate、REST Web 服务。
谢谢。
一个问题很多,我将提供简短的答案,并提供一堆指向相关文章和参考文档的链接。
控制器必须返回什么类型?
取决于您的注释和服务 RESTfulness。有三个注释可用于控制器:@Controller
、@RestController
和@RepositoryRestController
。
控制器是将类标记为控制器的基本注释。控制器端点方法的返回类型可以是很多东西,我邀请您阅读这篇专门的文章来掌握它。 在开发纯 REST 服务时,您将专注于使用 RestController 和 RepositoryRestController。RestController
是Controller
+ ResponseBody。它将终结点方法的返回值绑定到 Web 响应正文:
@RestController
public ItemController {
@RequestMapping("/items/{id}")
public Item getItem(@PathVariable("id") String id) {
Item item = ...
return item;
}
}
有了这个,当你点击http:/.../api/items/foo
时,Spring 会发挥它的魔力,自动将项目转换为具有相关 40X 状态代码和一些默认 HTTP 标头的 ResponseEntity。
在某些时候,您将需要对状态代码和标头进行更多控制,同时仍然受益于Spring Data REST的设置。那时您将使用带有ResponseEntity<Item>
的RepositoryRestController
作为返回类型,请参阅示例 Spring Data REST 引用。
如果给定项不存在,则在特定项的 GET 方法中使用什么 http 状态代码?
直言不讳地说:用HttpStatus.NOT_FOUND。您正在寻找不存在的资源,有问题。
话虽如此,完全由您决定如何处理项目中缺少的资源。如果您的工作流程证明这一点,那么缺少的资源可能是完全可以接受的,并且确实返回了 20 倍的响应,尽管如果您没有警告他们或提供一些文档,您可能会期望 API 的用户感到困惑(我们是习惯和惯例的生物)。但我仍然会从 404 状态代码开始。
(...) @Produces和@Consumes WS方法,但它有什么用?我的应用程序和方法如此工作,为什么要指定MediaType.APPLICATION_JSON_VALUE?Spring/SpringBoot 不会自动将 Item 或 ResponseEntity 转换为 json 吗?
@Consumes
和@Produces
分别与请求中的content-type
和accept
标头匹配。这是限制终结点方法接受的输入和提供的输出的一种方式。
由于我们谈论的是 REST 服务,因此 API 和服务客户端之间的通信应该是 JSON 格式的。多亏了Spring HATEOAS,答案实际上是用application/hal+json
内容类型格式化的。 在这种情况下,您确实不能打扰这两个注释。如果您开发一种接受不同内容类型(应用程序/文本、应用程序/json、应用程序/xml...)的服务,例如,向网站用户提供 HTML 视图,向服务的自动客户端提供 JSON 或 XML 响应,您将需要它们。
对于现实生活中的例子:
- Facebook为应用程序提供了Graph API,以读取/写入其图形,而用户则很乐意(?)浏览网页 。 谷歌
- 对谷歌地图API做同样的事情