How to serve one jersey resource or jetty servlet for different path

Today I'm trying to make an endpoint accessible in different paths. Such as I can go to http://localhost/ and http://localhost/hello for a same hello message.

I do got some solutions.

I'm using Jersey over Jetty. But whether or not you're using Jetty servlet or writing Jersey Resource, I think you will get some ideas.

Ps: I copy the code from my GitLab Snippets and will keep it update. So If you find something wrong, pls comment in GitLab

Using the regular expression in Jersey Resource

https://gitlab.com/snippets/1676612

package me.imlc.example.jetty.multiplehandler;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import me.imlc.example.jetty.multplehandler.HelloResource;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Objects;
import static org.junit.Assert.assertEquals;
public class RegexpResourceTest {
private static Server server;
private static CloseableHttpClient client = HttpClients.createDefault();
@BeforeClass
public static void beforeAll() throws Exception {
ResourceConfig rc = new ResourceConfig(RegexpResource.class);
ServletHolder holder = new ServletHolder(new ServletContainer(rc));
server = new Server(8080);
ServletContextHandler contextHandler = new ServletContextHandler(server, "/*");
contextHandler.addServlet(holder, "/*");
server.start();
}
@Test
public void canAccessByRootPath() throws Exception {
HttpGet get = new HttpGet("http://localhost:8080/hello");
String content = EntityUtils.toString(client.execute(get).getEntity());
assertEquals(content, "Hello, Lynn.");
}
@Test
public void canAccessByServicePath() throws Exception {
HttpGet get = new HttpGet("http://localhost:8080/service/hello");
String content = EntityUtils.toString(client.execute(get).getEntity());
assertEquals(content, "Hello, Lynn.");
}
@AfterClass
public static void afterAll() throws Exception {
if(Objects.nonNull(server)) server.stop();
if(Objects.nonNull(client)) client.close();
}
@Path("/{a:(.*)|service}")
public static class RegexpResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello, Lynn.";
}
}
}

Specify multiple paths for one servlet

https://gitlab.com/snippets/1676613

package me.imlc.example.jetty.multiplehandler;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Objects;
import static org.junit.Assert.assertEquals;
public class MultipleServletTest {
private static Server server;
private static CloseableHttpClient client = HttpClients.createDefault();
@BeforeClass
public static void beforeAll() throws Exception {
ResourceConfig rc = new ResourceConfig(RegexpResourceTest.RegexpResource.class);
ServletHolder holder = new ServletHolder(new ServletContainer(rc));
server = new Server(8080);
ServletContextHandler contextHandler = new ServletContextHandler(server, "/*");
contextHandler.addServlet(holder, "/*");
contextHandler.addServlet(holder, "/service/*");
server.start();
}
@Test
public void canAccessByRootPath() throws Exception {
HttpGet get = new HttpGet("http://localhost:8080/hello");
String content = EntityUtils.toString(client.execute(get).getEntity());
assertEquals(content, "Hello, Lynn.");
}
@Test
public void canAccessByServicePath() throws Exception {
HttpGet get = new HttpGet("http://localhost:8080/service/hello");
String content = EntityUtils.toString(client.execute(get).getEntity());
assertEquals(content, "Hello, Lynn.");
}
@AfterClass
public static void afterAll() throws Exception {
if(Objects.nonNull(server)) server.stop();
if(Objects.nonNull(client)) client.close();
}
@Path("/hello")
public static class MultipleServletResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello, Lynn.";
}
}
}

Serve one servlet in different context handler

https://gitlab.com/snippets/1676615

package me.imlc.example.jetty.multiplehandler;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Objects;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import static org.junit.Assert.assertEquals;
public class MultipleContextHandlerTest {
private static Server server;
private static CloseableHttpClient client = HttpClients.createDefault();
@BeforeClass
public static void beforeAll() throws Exception {
ResourceConfig rc = new ResourceConfig(MultipleContextHandlerResource.class);
ServletHolder holder = new ServletHolder(new ServletContainer(rc));
server = new Server(8080);
ServletContextHandler rootContext = new ServletContextHandler(server, "/*");
rootContext.addServlet(holder, "/*");
ServletContextHandler serviceContext = new ServletContextHandler(server, "/service/*");
serviceContext.addServlet(holder, "/*");
ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
contextHandlerCollection.setHandlers(new Handler[]{
rootContext, serviceContext
});
server.setHandler(contextHandlerCollection);
server.start();
}
@Test
public void canAccessByRootPath() throws Exception {
HttpGet get = new HttpGet("http://localhost:8080/hello");
String content = EntityUtils.toString(client.execute(get).getEntity());
assertEquals(content, "Hello, Lynn.");
}
@Test
public void canAccessByServicePath() throws Exception {
HttpGet get = new HttpGet("http://localhost:8080/service/hello");
String content = EntityUtils.toString(client.execute(get).getEntity());
assertEquals(content, "Hello, Lynn.");
}
@AfterClass
public static void afterAll() throws Exception {
if(Objects.nonNull(server)) server.stop();
if(Objects.nonNull(client)) client.close();
}
@Path("/hello")
public static class MultipleContextHandlerResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello, Lynn.";
}
}
}