Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAX-RS: OPTIONS for every Resource

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();
}
like image 823
Dennis Avatar asked Dec 05 '13 15:12

Dennis


People also ask

What are JAX-RS resources?

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.

What are the implementations of JAX-RS?

JAX-RS is a standard defined in Java Specification Request 311 (JSR-311) and Jersey / RESTEasy are implementations of it.

What is the role of @path in JAX-RS API?

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.


3 Answers

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:

  • curl -I -X OPTIONS http://myhost.com/test
  • curl -I -X OPTIONS http://myhost.com/test/asd/aasd/12/
  • etc.
like image 142
Dennis Avatar answered Oct 14 '22 01:10

Dennis


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());
        }
    }
}
like image 44
Heero Yui Avatar answered Oct 14 '22 02:10

Heero Yui


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())
        }
    }
}
like image 23
gmariotti Avatar answered Oct 14 '22 03:10

gmariotti