Here is a basic server setup with JAX-RS 3 using Jersey and Jetty 11 for the server. JAX-RS is Java API specification for RESTful web services using annotations. The project structure is as follows.
APIZenServer
├── src
│ └── main
│ └── java
│ └── net
│ └── jsloop
│ └── apizen
│ ├── APIZenServer.java
│ ├── HealthResource.java
│ └── MainResource.java
└── pom.xml
// APIZenServer.java
package net.jsloop.apizen;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.servlet.ServletContainer;
public class APIZenServer {
public static void main(String[] args) {
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setHost("0.0.0.0");
connector.setPort(8080);
server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
jerseyServlet.setInitParameter(
"jersey.config.server.provider.classnames",
String.join(",",
HealthResource.class.getCanonicalName(),
MainResource.class.getCanonicalName()
)
);
server.setHandler(context);
try {
server.start();
System.out.println("Server running at http://0.0.0.0:8080");
System.out.println("Health check: http://0.0.0.0:8080/health");
server.join();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.destroy();
}
}
}
// HealthResource.java
package net.jsloop.apizen;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@Path("/")
public class HealthResource {
@GET
@Path("/health")
@Produces(MediaType.APPLICATION_JSON)
public Response getHealth() {
return Response.ok("{\"status\": \"true\", \"health\": \"ok\"}").build();
}
}
// MainResource.java
package net.jsloop.apizen;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@Path("/")
public class MainResource {
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public Response getRoot() {
return Response.ok("{\"status\": \"ok\"}").build();
}
}
<!-- pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.jsloop</groupId>
<artifactId>APIZen</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jersey.version>3.1.10</jersey.version>
<jetty.version>11.0.25</jetty.version>
</properties>
<dependencies>
<!-- Jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- Jetty -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<archive>
<manifest>
<mainClass>net.jsloop.apizen.APIZenServer</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
We can run this direclty from IntelliJ or from command line. For command line, follow the below steps.
mvn clean package
java -jar target/APIZen-1.0-jar-with-dependencies.jar
The server has two endpoints. One the root /
and another /health
which returns a JSON response. The /health
endpoint is accessible at http://localhost:8080/health and returns {"status": "true", "health": "ok"}
.