An HTTP OPTIONS request is used to query the server for the list of HTTP verbs, supported by a given URI. This list is sent back in Allow response header.
In JAX-RS, an incoming OPTIONS request is automatically handled by the JAX-RS implementation without calling any resource method.
We can also explicitly use @OPTIONS annotation on a resource method. In that case, we have to set Allow header manually. We also have flexibility of controlling the values for Allow header depending on the other request parameters.
Examples
First, we are not going to use @OPTIONS annotation.
@Path("/")
public class MyResource {
@Path("/test")
@GET
public Response handle() {
Response r = Response.ok("test with GET, body content")
.build();
return r;
}
.............
}
To try examples, run embedded tomcat (configured in pom.xml of example project below):
mvn tomcat7:run
JAX-RS client:
public class MyClient {
public static void main(String[] args) {
MyClient.sendOptionsRequest("test");
}
public static void sendOptionsRequest(String uri) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/app/" + uri);
Response response = target.request()
.options();
MultivaluedMap<String, Object> headers = response.getHeaders();
System.out.printf("Allow Header: %s%n", headers.get("Allow"));
System.out.printf("status: %s%n", response.getStatus());
System.out.printf("body: '%s'%n", response.readEntity(String.class));
}
} OutputAllow Header: [HEAD,GET,OPTIONS] status: 200 body: ''
Following example shows multiple resource methods implemented for different verbs but for the same URI:
@Path("/")
public class MyResource {
.............
@Path("/test2")
@GET
public Response handle2() {
Response r = Response.ok("test2 with GET, body content")
.build();
return r;
}
@Path("/test2")
@POST
public Response handle3() {
Response r = Response.ok("test2 with POST, body content")
.build();
return r;
}
@Path("/test2")
@HEAD
public Response handle4() {
Response r = Response.ok("test2 with HEAD, body content")
.build();
return r;
}
.............
}
public class MyClient2 {
public static void main(String[] args) {
MyClient.sendOptionsRequest("test2");
}
} OutputAllow Header: [HEAD,POST,GET,OPTIONS] status: 200 body: ''
Explicitly using @OPTIONS
In this case, we have to set Allow header in the response ourselves.
@Path("/")
public class MyResource {
.............
@Path("/test3")
@GET
public Response handle5(){
Response r = Response.ok("test3 with GET, body content")
.build();
return r;
}
@Path("/test3")
@OPTIONS
public Response handle6(){
Response r = Response.ok("test3 with OPTIONS, body content")
.header("Allow", "GET")
.header("Allow", "OPTIONS")
.build();
return r;
}
}
public class MyClient3 {
public static void main(String[] args) {
MyClient.sendOptionsRequest("test3");
}
} OutputAllow Header: [OPTIONS, GET] status: 200 body: 'test3 with OPTIONS, body content'
Example ProjectDependencies and Technologies Used: - jersey-server 2.25.1: Jersey core server implementation.
- jersey-container-servlet 2.25.1: Jersey core Servlet 3.x implementation.
- JDK 1.8
- Maven 3.3.9
|