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 codeResteasyServletInitializer
source codeYou 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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With