Last active
August 29, 2015 14:19
-
-
Save BrainBacon/667e09373ae1992fcd59 to your computer and use it in GitHub Desktop.
CORS with JAX-RS and CDI with preflight
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- {beans.xml stuff here} --> | |
<interceptors> | |
<class>com.example.interceptor.CrossDomainInterceptor</class> | |
</interceptors> | |
<!-- {/beans.xml} --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.interceptor; | |
import javax.interceptor.InterceptorBinding; | |
import java.lang.annotation.*; | |
@Inherited | |
@InterceptorBinding | |
@Retention(RetentionPolicy.RUNTIME) | |
@Target({ElementType.METHOD, ElementType.TYPE}) | |
public @interface CrossDomain { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.filter; | |
import com.example.interceptor.CrossDomainInterceptor; | |
import com.sun.jersey.spi.container.ContainerRequest; | |
import com.sun.jersey.spi.container.ContainerResponse; | |
import com.sun.jersey.spi.container.ContainerResponseFilter; | |
import javax.ws.rs.container.PreMatching; | |
import javax.ws.rs.core.Response; | |
@PreMatching | |
public class CrossDomainFilter implements ContainerResponseFilter { | |
/** | |
* Add the cross domain data to the output for OPTIONS request (preflight) only | |
* | |
* @param containerRequest The container request (input) | |
* @param containerResponse The container response (output) | |
*/ | |
public ContainerResponse filter(ContainerRequest containerRequest, ContainerResponse containerResponse) { | |
if(containerRequest.getMethod().equals("OPTIONS")) { | |
Response response = Response | |
.ok() | |
.header("Access-Control-Allow-Headers", containerRequest.getHeaderValue("Access-Control-Request-Headers")) | |
.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD") | |
.build(); | |
response = CrossDomainInterceptor.crossDomainResponse(response, containerRequest.getHeaderValue("Origin")); | |
containerResponse.setResponse(response); | |
} | |
return containerResponse; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.interceptor; | |
import javax.enterprise.context.RequestScoped; | |
import javax.inject.Inject; | |
import javax.interceptor.AroundInvoke; | |
import javax.interceptor.Interceptor; | |
import javax.interceptor.InvocationContext; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.ws.rs.core.Response; | |
@CrossDomain | |
@Interceptor | |
@RequestScoped | |
public class CrossDomainInterceptor { | |
@Inject | |
HttpServletRequest request; | |
@AroundInvoke | |
protected Object invoke(InvocationContext ctx) throws Exception { | |
ctx.getParameters(); | |
if(request.getHeader("Origin") != null /* && {Put your domain restriction logic here} */) { | |
return crossDomainResponse((Response) ctx.proceed(), request.getHeader("Origin")); | |
} else { | |
return ctx.proceed(); | |
} | |
} | |
public static Response crossDomainResponse(Response response, String origin) { | |
if(origin != null) { | |
return Response | |
.fromResponse(response) | |
.header("Access-Control-Allow-Origin", origin) | |
.header("Access-Control-Allow-Credentials", "true") | |
.header("Access-Control-Expose-Headers","EXAMPLE-CUSTOM-HEADER") | |
.build(); | |
} | |
return response; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.endpoint; | |
import com.example.interceptor.CrossDomain; | |
import javax.ejb.Stateless; | |
import javax.inject.Inject; | |
import javax.ws.rs.*; | |
import javax.ws.rs.core.MediaType; | |
import javax.ws.rs.core.Response; | |
// CrossDomainInterceptor can be used at the class level to apply to all internal methods | |
@CrossDomain | |
@Path("/example") | |
@Produces(MediaType.APPLICATION_JSON) | |
@Stateless | |
public class ExampleEndpoint { | |
// Or CrossDomainInterceptor can be applied to a specific jax-rs Response method. | |
@CrossDomain | |
// CrossDomainInterceptor can be applied to any request method type. | |
@GET | |
public Response getExample() { | |
return Response.ok(/* exampleResponseData() */).build(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- {web.xml stuff here} --> | |
<servlet> | |
<!-- {your JAX-RS servlet stuff here} --> | |
<!-- Mapping the CrossDomainFilter --> | |
<init-param> | |
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name> | |
<param-value>com.example.filter.CrossDomainFilter</param-value> | |
</init-param> | |
</servlet> | |
<!-- {your JAX-RS servlet mapping here} --> | |
<!-- {/web.xml} --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment