I'm trying to setup my project with Jersey to basically have 2 servlets: a private one for access by the client application, and a public facing one that acts as an API. The api calls are a subset of the private ones. (In case this is relevant my client side is GWT with RestyGWT). My resources are all stored in either:
com.path.to.server.resources.internal
com.path.to.server.resources.api
Where the private servlet should encompass both of those packages, and the api should only use the api package.
I would like my internal calls to look like this:
https:// localhost:8445/resources/authentication/login
and my api calls to look like this:
https:// localhost:8445/api/users/getuser
My web.xml looks like this:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<!-- Servlets -->
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.path.to.server.resources.exceptionmappers;com.path.to.server.resources.api;com.path.to.server.resources.internal</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>com.path.to.server.ApiApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>com.path.to.server.ApiApplication</servlet-name>
<url-pattern>/api</url-pattern>
</servlet-mapping>
</web-app>
I have the ApiApplication setup like this:
public class ApiApplication extends ResourceConfig
{
public ApiApplication()
{
System.out.println("SETTING UP API");
packages("com.path.to.server.resources.exceptionmappers;com.path.to.server.resources.api");
}
}
Now that I have all that setup, I'm trying to hit my service. I'm using a DirectRestService that looks like this:
@Path("resources/authentication")
public interface AuthenticationService extends BaseService
{
@POST
@Path("/login/{loginType}")
@Produces(MediaType.APPLICATION_JSON)
Session login(@HeaderParam("Authorization") String authorization, @PathParam("loginType") UserTypes loginType);
@POST
@Path("/findActiveSession")
@Produces(MediaType.APPLICATION_JSON)
Session findActiveSession();
}
The server resource that implements that looks like this:
@Path("authentication")
public class AuthenticationResource extends BaseResource implements AuthenticationService
{
public Session login(String authorization, UserTypes loginType)
{
// Code to do stuff
}
public Session findActiveSession()
{
// Code to do stuff
}
}
When I visit https:// localhost:8445, the findActiveSession() method is called from my client, but I get a 404. The service URL as shown in Chrome's network monitor looks like this:
https:// localhost:8445/resources/authentication/findActiveSession
It's all very confusing as to which things need what paths. Things I'm not sure about:
Is the AuthenticationResource Path correct? Does it even need the Path annotation?
Is it correct for the private servlet to use the javax.ws.rs.core.Application?
Am I correctly setting up the custom servlet with the Application subclass (ApiApplication)?
I've finally come up with a solution that is working. I don't know if it's entirely correct, but it gives me the results I want:
My web.xml
<web-app id="WebApp_ID" version="3.0" [...]>
<!-- Servlet for direct client/server calls -->
<servlet>
<servlet-name>InternalApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
path.to.server.resources.exceptionmappers,path.to.server.resources.api,path.to.server.resources.internal
</param-value>
</init-param>
</servlet>
<!-- Servlet for API calls -->
<servlet>
<servlet-name>ApiApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
path.to.server.resources.exceptionmappers,path.to.server.resources.api
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>InternalApplication</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ApiApplication</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
I didn't end up needing the Application subclasses.