POST Request not working with CORS (Java EE7, Glassfish 4.1, JAX-RS 2.0)

1.5k views Asked by At

I used NetBeans IDE 8.0.1 "RESTful Web Services from database" wizard to map my table objects with JPA and JAX-RS 2.0. After the classes were created, with the project options "Test RESTful Web Services", NetBeans itself creates an interface (HTML, css).

This works fine in my localhost. I can connect to my database from the Web Services created, sending GET and POST (JSON) Requests.

Image 1 (Interface)

Now, I need to access from another domain different from my localhost, so I tried with CORS. Searching diferent post I used this code:

package CORS;

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.container.PreMatching;
import javax.ws.rs.ext.Provider;

@Provider
@PreMatching
public class CORSResponseFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException {
        response.getHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
        response.getHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }
}

And with this ApplicationConfig class created, the resource (CORSRequestFilter) was added:

package entities.service;

import java.util.Set;
import javax.ws.rs.core.Application;

@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        addRestResourceClasses(resources);
        return resources;
    }

    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(CORS.CORSResponseFilter.class);
        resources.add(entities.service.AppSettingsFacadeREST.class);
        resources.add(entities.service.CategoryFacadeREST.class);
        resources.add(entities.service.CityFacadeREST.class);
        resources.add(entities.service.EmailInitialSubscriptionFacadeREST.class);
        resources.add(entities.service.IdentityProviderFacadeREST.class);
        resources.add(entities.service.ItemFacadeREST.class);
        resources.add(entities.service.ItemHistoryFacadeREST.class);
        resources.add(entities.service.ItemStatusFacadeREST.class);
        resources.add(entities.service.PhotoFacadeREST.class);
        resources.add(entities.service.UserFacadeREST.class);
        resources.add(entities.service.WantedItemsFacadeREST.class);
    }

}

And it works perfectly for a while! I was able to connect to my database to my Glassfish server from another domain using the RESTful web services just fine. I even develop an AngularJS app and could use the RSWebServices too.

Then I started to receive this error:

XMLHttpRequest cannot load http://xx.x.xxx.xx:8080/freeproject/webresources/entities.emailinitialsubscription. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://xxxxxxxxxxx.com' is therefore not allowed access. The response had HTTP status code 400.

The preflight request is returned with a status 200 OK. But the POST request is failed.

Searching on internet I found that Oracle itself https://blogs.oracle.com/theaquarium/entry/supporting_cors_in_jax_rs tells me to follow this post: http://www.developerscrappad.com/1781/java/java-ee/rest-jax-rs/java-ee-7-jax-rs-2-0-cors-on-rest-how-to-make-rest-apis-accessible-from-a-different-domain/

So, I tried that and I added a new class: resources.add(CORS.CORSRequestFilter.class):

package CORS;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;

@Provider
@PreMatching
public class CORSRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter( ContainerRequestContext requestCtx ) throws IOException {

        String path = requestCtx.getUriInfo().getPath();

        // IMPORTANT!!! First, Acknowledge any pre-flight test from browsers for this case before validating the headers (CORS stuff)
        if ( requestCtx.getRequest().getMethod().equals( "OPTIONS" ) ) {
            requestCtx.abortWith( Response.status( Response.Status.OK ).build() );
        }
    }
}

But it doesn't work. The abortWith function stop the chain of requests and the POST request is never sent.

What can I do here? Any help will be highly appreciated.

0

There are 0 answers