I am using a JAX-RS interface with XMLHttpRequest (XHR). Due to the XHR preflight, XHR send always OPTIONS before calling the real resource.
Now I have dozens of methods and I need the OPTIONS for every resoruce. Is there any way to do this automatically? I dont want to write dozens of methods like:
@OPTIONS
@Path("/{id}")
@PermitAll
public Response optionsById() {
return Response.status(Response.Status.NO_CONTENT).build();
}
@OPTIONS
@Path("/{id}/data")
@PermitAll
public Response optionsByData() {
return Response.status(Response.Status.NO_CONTENT).build();
}
In practice, in Java code using a JAX-RS implementation, it usually refers to a resource class, a Java class with methods that handle REST HTTP API endpoints related to the same entity. The HTTP request method defines the intended operation on the entity.
JAX-RS is a standard defined in Java Specification Request 311 (JSR-311) and Jersey / RESTEasy are implementations of it.
The @Path annotation's value is a partial URI path template relative to the base URI of the server on which the resource is deployed, the context root of the application, and the URL pattern to which the JAX-RS runtime responds.
UPDATE 09/12/2013: THIS DOES NOT WORK. Using this all @GET/@DELETE/@POST/@PUT are not working any more.
Finally I solved my problem. I created a super class OptionsResource
, from which all resources inherit. This resoruce contains:
// Match root-resources
@OPTIONS
@PermitAll
public Response options() {
return Response.status(Response.Status.NO_CONTENT).build();
}
// Match sub-resources
@OPTIONS
@Path("{path:.*}")
@PermitAll
public Response optionsAll(@PathParam("path") String path) {
return Response.status(Response.Status.NO_CONTENT).build();
}
An example:
@Path("/test")
public class TestResource extends OptionsResource {
@GET
@Produces("text/plain;charset=UTF-8")
public Response index() {
return Response.status(Status.OK).entity("works").build();
}
}
This matches:
The java version:
@Provider
@PreMatching
public class OptionFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
if (requestContext.getMethod().contentEquals("OPTIONS")) {
requestContext.abortWith(Response.status(Response.Status.NO_CONTENT).build());
}
}
}
Quite a late reply, but a much nicer solution is to use a filter that catches all the OPTIONS call before path matching. In Kotlin, it will look like this:
@Provider @PreMatching
class OptionsFilter: ContainerRequestFilter {
override fun filter(requestContext: ContainerRequestContext) {
if (requestContext.method == "OPTIONS") {
requestContext.abortWith(Response.status(Response.Status.NO_CONTENT).build())
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With