REST - 使用 Spring MVC 返回创建的对象

Posted

技术标签:

【中文标题】REST - 使用 Spring MVC 返回创建的对象【英文标题】:REST - Returning Created Object with Spring MVC 【发布时间】:2013-04-14 04:40:23 【问题描述】:

我有一个接受 JSON 对象的 REST 调用,比如说一个人。创建这个对象(验证并保存到数据库)后,我需要返回新创建的 JSON 对象。

我认为标准做法是返回201 Accepted,而不是立即返回对象。但我的应用程序立即需要新创建的对象。

我有一个控制器方法,它接受一个 POST 调用,调用一个服务类,然后调用一个使用 Hibernate 创建对象的 DAO。将其保存到数据库后,我将调用另一个控制器方法,该方法获取人员的 ID 并返回对象。

我的问题,这是更好的方法吗?即调用另一个Controller方法来获取新创建的对象。或者 POST 调用本身应该返回 Object。

主要问题是: 调用另一种方法需要往返,我想这是一种矫枉过正。 (服务->DAO->休眠->数据库)。相反,我认为我应该在将对象保存在同一个调用中后立即从数据库中获取它(从处理 POST 的方法中)。

这里的架构标准是什么?

【问题讨论】:

201 是“已创建”。 202 是“接受”。 【参考方案1】:

您可以在使用@ResponseBody 将实体对象持久化之后,在@ResponseStatus 之后返回实体对象,但这不是标准的,因此您的客户端必须了解此自定义,否则如果您的客户端依赖于标准 API,您必须坚持通过返回 void 来达到标准。

【讨论】:

【参考方案2】:

尝试使用ResponseEntity,它会返回 HTTP 状态以及您需要的对象。

示例代码是(这是我返回客户对象的代码,根据您的需要进行更改):

// imports (for your reference)
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

// spring controller method
@RequestMapping(value = "getcust/custid", method = RequestMethod.GET, produces="application/json")
public ResponseEntity<Customer> getToken(@PathVariable("custid") final String custid, HttpServletRequest request) 

    customer = service.getCustById(custid);

    return new ResponseEntity<Customer>(customer, HttpStatus.OK);

阅读此documentation 以了解更多信息。那里提供了一些示例代码。

【讨论】:

这是 GET。但是如果你想用 POST 返回客户对象怎么办。那就是创建然后立即返回。您是调用上述 GET 方法返回还是在保存后立即获取 JSON 对象,在同一个 POST 调用方法中? 这是一个示例代码,供您理解。我只是想向您解释如何返回一个对象以及 http 状态。如果您正在使用休眠,您可以获得持久对象,您可以立即返回该对象以及 Http (201) 状态。【参考方案3】:

来自HTTP specification for POST:

如果在源服务器上创建了资源,则响应应该是 201(已创建)并包含描述请求状态并引用新资源的实体,以及 Location 标头(参见第 14.30 节)。

您将在响应正文中返回的内容取决于您对an entity which describes the status of the request and refers to the new resource 的解释有多严格 - 许多实现只是返回新创建实体本身的表示。最重要的是将响应中的 Location 标头设置为新创建资源的 URI,以便客户端可以根据需要立即获取它。

【讨论】:

问题在于返回创建的实体的方法。 1.) 通过调用另一个控制器的 GET 方法或 2.) 从创建实体的同一个 POST 方法返回。 你看我的回答了吗?或者您是在问如何在 Spring 中专门从 POST 中返回一个实体? 是的,这回答了第一部分。 “应该归还什么”。但问题的另一部分是“在响应正文中返回对象本身的标准/更好的方法是什么”。不在位置标题中。我理解并同意我应该返回201 Created,然后在标头中返回该资源的位置/URI。但我们的要求是在正文中返回实际的 JSON 对象。可以告诉我吗? and many implementations simply return a representation of the newly created entity itself - 也就是直接从您的 post 方法返回实体,或者将其包装在结果对象中并返回。

以上是关于REST - 使用 Spring MVC 返回创建的对象的主要内容,如果未能解决你的问题,请参考以下文章

如何正确实现使用 Spring MVC\Boot 返回图像列表的 REST 服务?

使用 REST 模板和 JSON 响应格式在 Spring MVC 上返回 Http Status 500

Spring MVC - 如何在 Rest Controller 中以 JSON 形式返回简单字符串

Spring mvc REST和mongoDB日期字段的问题

如何使用 Spring MVC 返回视频,以便可以使用 html5 <video> 标签进行导航?

Spring MVC、Rest 和 Shiro。 @RequiresAuthentication 不起作用