CORS support for Jax-rs 2 AsyncResponse? - java

I created a rest webservice using Jax-rs 2. It uses the AsyncResponse to return the response. How I can add CORS support to my rest web services ? So any one can access it with out any cross domain issues ?
My sample rest webservice is as follows
#GET
#Path("/test")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public void test(#Suspended AsyncResponse asyncResponse){
asyncResponse.resume(Response.ok().build());
}
Thank you!

RestEasy has the CorsFilter. But since you are using Glassfish, you are most likely using Jersey. Jersey doesn't seem to have any such class we can use. That said, the CorsFilter for RestEasy implements ContainterRequestFilter and ContainerResponseFilter (Note, this is a Jersey 2.x (JAX-RS 2.0) feature).
See Filters and Interceptors for more information
You can also see the source code for the CorsFilter here at GrepCode. You'll basically want to implements something similar to that class, then register it is as a singleton with the application.

Related

Java Decorate Functions

I am new to Java so apologies if this is a simple thing. I have built decorators in Python for authorizing RESTFul endpoints in Flask and have just built my first Java Webserver but am unable to figure out how to create a similar decorator in Java.
I want to do some pre-checks before running the method (i.e. is the user allowed to access this route). Ideally this would be a decorator like #authorize that, if authorized, will execute the method, but if unauthorized then it would through a 403 error instead.
#Path("/")
public final class HelloWorld {
#GET
#Path("/hello")
#authorize // How would I implement this?
public String sayHelloWorld() {
return "Hello World!";
}
}
EDIT: I am using Grizzly as the web Framework and I will be using an external Policy Management System (Apache Ranger) for managing authorization.
First of all: defining such custom annotations is exactly how you can approach such things in Java. The JAX-RS specification provides all the things you need for such kind of method binding.
The thing that is slightly more complicated: how to nicely do that for the framework that you are using.
With JAX-RS and Jersey for example, creating your own annotations is well documented. And Jersey might be a good starting point, as that is simply a straight forward way to get JAX-RS working.
So, first you start by learning how to use Jersey in general, for example from vogella. Next: you can start to add your custom annotations, see here for an example.
There is even an existing question about using custom annotations for access validation.

Moving ClientFilter from Jersey to Jersey 2

I am trying to migrate the usages of Jersey Client in my codebase from com.sun.jersey.client to org.glassfish.jersey.client.
In multiple parts of the codebase I am creating classes that inherit from ClientFilter and override the handle method.
What is the replacement of ClientFilter in Jersey 2 and how should I change the places I use it?
See Jersey docs section Client Filters. Basically there are ClientRequestFilter and ClientResponseFilter. The former is called before the request goes out and the latter is called on the incoming response. See also this post for more info on the flow.

How to use Jersey as JAX-RS implementation without web.xml?

I have read that from JavaEE 6 web.xml is optional.
So without web.xml, how can I tell the application server to use Jersey as the implementation for JAX-RS specification?
What #AlexNevidomsky wrote in his answer is correct, as far as how to implement the app configuration with no web.xml; you use an #ApplicationPath annotation on an Application subclass.
#ApplicationPath("/api")
public class AppConfig extends Application {}
For more information on deployment options, see the Jersey Docs: Chapter 4. Application Deployment and Runtime Environments
Or more commonly, with Jersey as implementation, we would extend ResourceConfig (which extends Application).
#ApplicationPath("api")
public class AppConfig extends ResourceConfig {
public AppConfig() {
packages("package.to.scan");
}
}
So how is this implemented...
First things first, not all Java EE servers use Jersey. Actually the only ones I know that use Jersey are Glassfish and WebLogic. JBoss uses Resteasy. Tom EE uses CXF. WebSphere uses Apache Wink. Those are the only ones I can think of.
So I guess the question is "How does the Server know how to load the JAX-RS application?"
Servlet 3.0 introduced the pluggability mechanism, which makes use of a ServletContainerInitializer. How it works is that when the Server/Servlet container is started, it scans jars for a META-INF/services folder with a file named javax.servlet.ServletContainerInitializer. This file should include one or more fully qualified names of implementations of the ServletContainerInitializer.
This interface has only one method
void onStartup(java.util.Set<java.lang.Class<?>> c, ServletContext ctx)
The Set<Class<?> will be a list of classes, fitting the criteria in the #HandlesTypes annotation on the ServletContainerInitializer implementation. If you look at Jersey's implementation
#HandlesTypes({ Path.class, Provider.class, Application.class, ApplicationPath.class })
public final class JerseyServletContainerInitializer
implements ServletContainerInitializer {
You should notice some familiar annotation classes, as well as the Application.class. All these classes matching the criteria, while scanning, are added to the Set passed to the onStartup method.
If you scan the rest of the source code, you will see all the registration being done with all of those classes.
Resteasy uses
#HandlesTypes({Application.class, Path.class, Provider.class})
public class ResteasyServletInitializer implements ServletContainerInitializer
I won't get into to others.
Some source you can look at...
JerseyServletContainerInitializer source code
ResteasyServletInitializer source code
JAX-RS specs
You don't have to specify anything in web.xml. Define an activator class:
#ApplicationPath("/rest")
public class _JaxRsActivator extends javax.ws.rs.core.Application {
static {
//Check some system init on REST init.
Config.initCheck();
}
}

Web service that works as REST and SOAP using Java/Jersey

Can I have the same service having simultaneously both REST and SOAP interfaces?
I currently have a REST service implemented in Java using EJB and Jersey:
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Stateless
#Path("test")
public class TestExternalService {
#EJB
private com.test.ejb.db.TestService testService;
#GET
#Path("/status")
#Produces("text/*")
public String status() {
return "ok";
}
}
How can I make changes in my class to also implement a SOAP interface?
Basically, Jersey is JAX-RS implementation, so you cannot have SOAP web-services here. You could take Apache CXF, which is implementation for both JAX-RS and JAX-WS and you would be able to combine your web-services in both architectural styles.
Here is a solution to expose an implementation as both rest and soap web service. Similar to what zack suggested in the comment.
You may have to do some refactoring if you already have the service supporting jax-rs as you pasted above.
The solution is to have two sets of interfaces and implementation. One supporting jax-rs and one jax-ws. You can still have your processing done in the ejb.
Example,
Do not annotate your ejb (say EService) with jax-rs.
Have an interface X and Ximpl class to support restful calls. This will support jax-rs, so basically be annotated with jax-rs. Ofcourse, this can still use jersey. Ximpl will reference the EJB EService and delegate the processing to it.
Have an interface Y and YImpl to support soap based calls. This will support jax-ws, so will be annotated with jax-ws. Yimpl will reference the EJB EService and delegate the processing to it.
If you have a web deployment descriptor, in your web deployment descriptor define different servlets and mapping for rest and soap.

What is a Jersey Filter?

I want to know basically what a Jersey filter is and how is it related to a servlet filter? Are they the same? What are the main patterns of using a Jersey Filter?
Technically, a Jersey filter is not a servlet filter. However, you can use a Jersey filter for many of the same things that you would use a servlet filter for - cross-cutting concerns that affect all (or some, or most) the services that Jersey exposes.
As the previous answer states, Jersey comes with two filters, but you can usefully implement the Jersey interfaces ContainerRequestFilter or/and ContainerResponseFilter if you don't want to extend them. You're not limited to these two.
Another Jersey interface to keep in mind is ResourceFilter - this interface can be implemented for a filter that affects only some of the services.
The first part of your question may be answered in the Jersey documentation. A Jersey filter is not the same as a servlet filter.
There are two filters included in Jersey, a filter for logging requests and one for compression (GZip).
Another use case for a custom filter would be authentication or authorization.

Categories