Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
887 views
in Technique[技术] by (71.8m points)

json - In REST / Java, what should I return if my object is null?

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;
}

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.

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

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.

Three questions:

  • is HTTP 204 the right response to be returned?
  • how can I control that via annotations? Via other configuration?
  • what is the standard REST best practice regarding null objects?

Thanks

EDIT

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.

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 
}

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


Related Q&As


EDIT

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) {
    ...
}

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...