ptntialunrlsd ptntialunrlsd - 28 days ago 10
reST (reStructuredText) Question

JAX RS POST API not supporting HEAD request

As per the Jersey documentation,



By default the JAX-RS runtime will automatically support the methods HEAD and OPTIONS, if not explicitly implemented. For HEAD the runtime will invoke the implemented GET method (if present) and ignore the response entity (if set). For OPTIONS the Allow response header will be set to the set of HTTP methods support by the resource. In addition Jersey will return a WADL document describing the resource.



So, if I have a Jersey
POST
API, will it not support
HEAD
call? In my case, it's supporting only
OPTIONS
call, which returns allowed methods as
POST
and
OPTIONS
. How do you go about supporting the
HEAD
calll?

Answer

The quote you gave answers half of your question:

For HEAD the runtime will invoke the implemented GET method (if present) and ignore the response entity (if set).

So to enable the HEAD method on your enpoint you have two options:

  • implement GET and Jersey will automatically provide the default implementation of HEAD
  • implement HEAD explicitly

The reason why POST method cannot be used to provide a default HEAD implementation is that POST method is neither safe nor idempotent (as defined in the HTTP standard). This means that if someone calls a POST method they must assume that it will have consequences on the application/resource state. GET and HEAD on the other side are both safe and idempotent so they must not change the state.

To answer the second part of your question - implementing HEAD doesn't differ from implementing other HTTP methods:

import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("api/ping")
public class MyResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String ping() {
        return "pong!";
    }

    @HEAD
    public Response getHeaders() {
        return Response.status(200).
                header("yourHeaderName", "yourHeaderValue").build();
    }
}