如果 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字符串 的