Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey 'NoContent' response returns 200 instead of 204

I am using Jersey (1.18) to build a REST API for my WebApplication. In a part of my code I have the following snippet.

return Response.status(Status.NO_CONTENT).entity(err_message).build();

where Status is an instance of com.sun.jersey.api.client.ClientResponse.Status;

According to Jersey Documentation NO_CONTENT should return a 204 code, instead of this, the http response has a header with 200 code.

NO_CONTENT
public static final ClientResponse.Status NO_CONTENT
204 No Content, see HTTP/1.1 documentation.

I tried to change the aforementioned code to

return Response.noContent().entity(err_message).build();

But the issue still exists. As a side note, using NOT_FOUND instead of NO_CONTENT, return a 404 header as expected.

Any suggestion on 'How can I return 204 code?', is this a bug or I am doing something wrong.

Note: Not a duplicate of Returning 200 response code instead of 204

like image 942
Athafoud Avatar asked Jul 27 '15 14:07

Athafoud


People also ask

When to return 204 No Content?

The 204 (No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body. While 200 OK being a valid and the most common answer, returning a 204 No Content could make sense as there is absolutely nothing to return.

How to resolve status code 204?

By default, 204 (No Content) the response is cacheable. If caching needs to be overridden then the response must include cache respective cache headers. For example, you may want to return status 204 (No Content) in UPDATE operations where request payload is large enough not to transport back and forth.

When to use 204 response code?

The HTTP 204 No Content success status response code indicates that a request has succeeded, but that the client doesn't need to navigate away from its current page. This might be used, for example, when implementing "save and continue editing" functionality for a wiki site.

Can 204 response have body?

The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.


2 Answers

See this SO answer which says,

...204 means "No Content", meaning that the response contains no entity, but you put one in it. It's likely that Jersey is switching it to a 200 for you, which is basically identical to a 204 except that it contains a response entity.

Finally, you can get 204 responses very simply by a couple of built-in behaviors: void methods and null return values both map to a 204 response. Otherwise, simply return Response.status(204).build().

In other words, if you want "NO_CONTENT" then don't include content in your response.

like image 124
Paul Avatar answered Nov 15 '22 12:11

Paul


After a little more digging I have found the problem. The W3c Documentation gives a hint.

I am quoting

10.2.5 204 No Content

The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant.

If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view.

The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.

In my code I have entity(err_message) which causes the problem. By removing it the 204 is returned correctly. I think somehow the Jersey or 'someone' casts the response to 200 since it has content.

Update (02/05/2015)

This blog post link (posted earlier today as an answer and then deleted), gives some additional insights about situation. Based on the content of the blog post, whenever there is any content in the HTTP response the following method is invoked. This method sets the status code back to 200.

private void commitWrite() throws IOException {
   if (!isCommitted) {
       if (getStatus() == 204)
           setStatus(200);
       isCommitted = true;
       o = responseWriter.writeStatusAndHeaders(size, ContainerResponse.this);
   }
}

We can say that Jersey detects that since there is some content in the response, the status code was wrongly set to 204 and it changes it to the appropriate 200.

like image 24
Athafoud Avatar answered Nov 15 '22 11:11

Athafoud