如果 Spring MVC 控制器方法不返回值,返回啥?

Posted

技术标签:

【中文标题】如果 Spring MVC 控制器方法不返回值,返回啥?【英文标题】:What to return if Spring MVC controller method doesn't return value?如果 Spring MVC 控制器方法不返回值,返回什么? 【发布时间】:2012-10-02 00:28:54 【问题描述】:

我正在使用 jQuery 的 $.getJSON() 对我的简单 Spring MVC 后端进行异步调用。大多数 Spring 控制器方法如下所示:

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget,
    @RequestParam("type") String type) 
    return someDAO.getSomeData(widget, type);
   

我进行了一些设置,以便每个控制器将 @ResponseBody 作为 JSON 返回,这是客户端所期望的。

但是当一个请求不应该向客户端返回任何内容时会发生什么?我可以:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) 
    ...

如果不是,这里使用什么合适的语法?

【问题讨论】:

我假设如果你不返回任何东西,就不会有任何内容被发送回来? 我想我仍然会返回某种 POJO,即使在您的解决方案的版本 1 中它只是包装了一个“成功”布尔值或类似的东西。然后,您在所有 AJAX 方法中都有一个一致的模式,并且当您确实需要返回一些东西时,更容易构建一些东西! 与答案的建议相反,您在第二次 sn-p 中第一次拥有的内容非常好,并且是处理 POST 数据的正确方法。 【参考方案1】:

你可以返回void,然后你必须用@ResponseStatus(value = HttpStatus.OK)标记你不需要@ResponseBody的方法

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void updateDataThatDoesntRequireClientToBeNotified(...) 
    ...

只有 get 方法会隐式返回 200 状态码,所有其他方法都执行以下三件事之一:

返回 void 并用@ResponseStatus(value = HttpStatus.OK) 标记方法 返回一个对象并用@ResponseBody标记它 返回一个HttpEntity 实例

【讨论】:

其实你不需要设置@ResponseStatus,也不应该设置。只需在 void 处理程序上使用 @ResponseBody 就足够了。 我认为对于 void 方法返回 204 No Content 而不是 200 会更好 @raspacorp 200 对 POST 来说是正确的,因为它并不意味着有正文。 @BrettRyan 只是作为评论,至少对于 REST API,通常的做法是使用 POST 来创建内容,在这种情况下,它通常返回创建的实体的 id ,完整创建的实体或读取操作的链接。从 REST API 的角度来看,没有内容的 200 状态返回可能会令人困惑。 @ams 如果我没有同时使用 (@ResponseBody AND @ResponseStatus(value = HttpStatus.OK)) 选项,那么会发生什么???【参考方案2】:

您可以简单地返回带有适当标头的 ResponseEntity:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...)
....
return new ResponseEntity(HttpStatus.OK)

【讨论】:

如果有人遇到与我相同的问题,这在旧版本的 spring (4.1.1) 上不起作用,我会收到 500 个错误。我升级到 4.2.0,效果很好 这也是我返回空 200 的首选方式。由于 Spring 4.1 改用构建器模式: return ResponseEntity.ok().build(); 虽然似乎可以编译,但它给出了以下警告ResponseEntity is a raw type. References to generic type ResponseEntity<T> should be parameterized 我使用 ResponseEntity> 作为返回类型。没有警告,可以返回任何响应类型【参考方案3】:

您可以返回“ResponseEntity”对象。 在构造响应对象(包含响应正文和 HTTP 状态码)和从响应对象中获取信息时,使用“ResponseEntity”对象都非常方便。

getHeaders()、getBody()、getContentType()、getStatusCode() 等方法使读取 ResponseEntity 对象的工作变得非常容易。

您应该使用 ResponseEntity 对象,其 http 状态代码为 204(无内容),专门用于指定请求已被正确处理并且响应正文故意为空白。 使用适当的状态码来传达正确的信息非常重要,尤其是当您正在制作一个将被多个客户端应用程序使用的 API 时。

【讨论】:

在浏览器中设置@ResponseStatus(HttpStatus.NO_CONTENT)为我解决了XML Parsing Error: no root element found【参考方案4】:

是的,您可以使用 @ResponseBody 和 void 返回类型:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) 
    ...

【讨论】:

那么返回类型是什么......是 HTTP 状态码吗? @techBeginner 在这种情况下为 200(OK)。【参考方案5】:

返回 void @ResponseBody 没有任何问题,您应该为 POST 请求。

使用 HTTP 状态代码来定义异常处理程序例程中的错误,而不是其他人提到成功状态。您拥有的普通方法将返回您想要的200 响应代码,然后任何异常处理程序都可以返回错误对象和不同的代码(即500)。

【讨论】:

【参考方案6】:

但是随着您的系统在规模和功能上的增长......我认为始终返回一个 json 并不是一个坏主意。更多的是建筑/“大规模设计”问题。

您可以考虑始终返回具有两个已知字段的 JSON:代码和数据。其中 code 是一个数字代码,指定要完成的操作是否成功,而 data 是与请求的操作/服务相关的任何附加数据。

来吧,当我们使用后端服务提供者时,可以检查任何服务以查看它是否运行良好。

所以我坚持,不要让 spring 管理这个,公开混合返回操作(一些返回数据,其他什么都没有......).. 确保您的服务器公开一个更同质的接口。在一天结束时更简单。

【讨论】:

以上是关于如果 Spring MVC 控制器方法不返回值,返回啥?的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC @Controller中返回值为void类型

Spring mvc 发现不明确的映射。无法映射控制器 bean 方法

Spring MVC @Controller控制器方法String字符串 的

Spring MVC @Controller控制器方法String字符串 的

仅从 Spring MVC 3 控制器返回字符串消息

Spring MVC @ModelAttribute详解