corsjax-rscross-domainjava-ee-7wildfly-8

How to enable Cross domain requests on JAX-RS web services?


I developed a set of restful web services. I couldn't call any of these methods from remote clients due to the error No 'Access-Control-Allow-Origin' header is present on the requested resource.

The services work perfectly on localhost. Is there any changes or configs to do on the server side to resolve the issue. i.e. to enable cross domain requests.

I'm using WildFly 8, JavaEE 7


Solution

  • I was wondering the same thing, so after a bit of research I found that the easiest way was simply to use a JAX-RS ContainerResponseFilter to add the relevant CORS headers. This way you don't need to replace the whole web services stack with CXF (Wildfly uses CXF is some form, but it doesn't look like it uses it for JAX-RS maybe only JAX-WS).

    Regardless if you use this filter it will add the headers to every REST webservice.

    package com.yourdomain.package;
    
    import java.io.IOException;
    
    import javax.ws.rs.container.ContainerRequestContext;
    import javax.ws.rs.container.ContainerResponseContext;
    import javax.ws.rs.container.ContainerResponseFilter;
    import javax.ws.rs.ext.Provider;
    
    @Provider
    public class CORSFilter implements ContainerResponseFilter {
    
       @Override
       public void filter(final ContainerRequestContext requestContext,
                          final ContainerResponseContext cres) throws IOException {
          cres.getHeaders().add("Access-Control-Allow-Origin", "*");
          cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
          cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
          cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
          cres.getHeaders().add("Access-Control-Max-Age", "1209600");
       }
    
    }
    

    Then when I tested with curl, the response had the CORS headers:

    $ curl -D - "http://localhost:8080/rest/test"
    HTTP/1.1 200 OK
    X-Powered-By: Undertow 1
    Access-Control-Allow-Headers: origin, content-type, accept, authorization
    Server: Wildfly 8
    Date: Tue, 13 May 2014 12:30:00 GMT
    Connection: keep-alive
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Credentials: true
    Transfer-Encoding: chunked
    Content-Type: application/json
    Access-Control-Max-Age: 1209600
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
    

    My understanding is that it's the @Provider annotation that tells the JAX-RS runtime to use the filter, without the annotation nothing happens.

    I got the idea about using the ContainerResponseFilter from a Jersey example.