在 REST/Java 中,如果我的对象为空,我应该返回什么?

2022-01-21 00:00:00 json rest java jax-rs jersey

我有一个简单的 POJO,我用 REST 注释进行了如下注释:

I have a simple POJO that I annotated with REST annotations as follows:

@GET
@Path("/domains/{domainid}")
@Override
public Domain getDomain(@PathParam("domainid") UUID domainID) throws Exception {
    logger.info("Retrieving domain "+ domainID);
    Domain d = null;
    try {
        d = MyClient.getDomains().get(domainID.toString());
        logger.debug("Returning "+d.getName());
    } catch (Exception e) {
        logger.error("Could not retrieve domain", e);
    }
    return d;
}

请注意,包含 d.getName() 的日志语句实际上可以抛出 NPE,然后将其捕获并记录下来.这不漂亮,但这也不是重点.

Note that the log statement including d.getName() can actually throw an NPE which is then caught and logged. That's not pretty but it's also not the point here.

最终不管d有没有值,我都返回.

Ultimately whether d has a value or not, I return it.

如果是 null 值,我的客户端会收到 HTTP 204 状态代码.这是 wget 显示的内容:HTTP request sent, waitinging response... 204 No Content

In the case of a null value, my client receives an HTTP 204 status code. This is what wget displays: HTTP request sent, awaiting response... 204 No Content

奇怪的是,我的浏览器一动不动.他们仍然显示上一页(我认为当没有收到内容时保持原样是有意义的).我本来希望是空白页.

Oddly enough, my browsers don't budge an inch. They still display the previous page (I suppose it makes sense to stay put when no content is received). I would have expected a blank page.

三个问题:

  • HTTP 204 是要返回的正确响应吗?
  • 如何通过注释控制它?通过其他配置?
  • 关于空对象的标准 REST 最佳实践是什么?

谢谢

这里有一个关于同一主题的好问题:找不到REST资源时返回404是否正确?

There is a great question on the very same topic here: Is it correct to return 404 when a REST resource is not found?

推荐答案

如果请求试图 GET/locate/find 资源,但找不到,传统上我们应该发送 404 Not Found.如需进一步讨论请参阅此处.

If the request is trying to GET/locate/find a resource, and it can't be found, traditionally, we should send a 404 Not Found. For further discussion see here.

话虽如此,我通常喜欢让我的资源方法返回 Response,因为它更容易以我想要的方式微调响应(一点点 - 不多 - 更多细节 这里).但是看到您的方法如何覆盖接口契约(并返回模型对象),JAX-RS 为我们提供了一个很好的异常层次结构,这些异常层次结构将映射到特定的响应/状态.该列表可以在这里查看.

That being said, I generally like to have my resource methods return Response, as it's easier to fine tune the response the way I want (a little - not much - more detail here). But seeing as how your method is overriding an interface contract (and returning a model object), JAX-RS gives us a nice hierarchy of exceptions that will get mapped to a particular response/status. The list can be seen here.

因此,在您的特定情况下,如果找不到资源,您可以抛出 WebApplicationException(Response.Status.NOT_FOUND)NotFoundException,然后异常将被映射到 404 Not Found.类似的东西

So in your particular case, if the resource can't be found, you can throw a WebApplicationException(Response.Status.NOT_FOUND) or a NotFoundException, and the exception will be mapped to a 404 Not Found. Something like

d = MyClient.getDomains().get(domainID.toString());
if (d == null) {
    throw new NotFoundException();  // <-- JAX-RS 2.0
    // or throw new WebApplicationException(Response.Status.NOT_FOUND);
                                    // ^^  JAX-RS 1.x 
}

当抛出异常时该方法将退出,并且客户端将收到状态为 404 Not Found 的响应.

The method will exit when the exception is thrown, and the client will receive a response with a 404 Not Found status.

相关问答

  • 如何在不依赖 JAX-RS 实现的情况下捕获 404 (NotFoundException)?
  • 找不到REST资源时返回404是否正确?

编辑

在第一行我说如果请求试图获取/定位/查找资源..",但实际上,这几乎适用于我们使用的所有情况URI 模板,无论是用于 GET、POST、PUT、DELETE 还是其他.考虑这个例子

In the first line I stated "If the request is trying to GET/locate/find a resource..", but really, this applies to almost all cases we are using URI templates, whether it is for a GET, POST, PUT, DELETE, whatever. Consider this example

@PUT
@Path("/customers/{id}")
public Response updateCustomer(@PathParam("id") long id, Customer customer) {
    ...
}

这是一种允许客户端通过 PUT 更新客户的方法.客户端在尝试更新之前应该知道资源的完整 URI.如果在数据库中找不到 {id} 参数(用于查找),则资源不存在,并且还应向客户端返回 404 Not Found.

Here is a method that allows the client to update a customer via a PUT. The client should know the complete URI to the resource before trying to update it. If the {id} parameter (used for lookup) is not found say in a database, then the resource doesn't exist, and a 404 Not Found should also be returned to the client.

相关文章