How to create a simple HTTP server in Java with Undertow
You can use the Undertow project to spin up an embedded web server, inside your Java app.
Sometimes, we just want something really simple. A simple breakfast. Or perhaps, a simple web server, embedded in a Java app.
To add an embedded web server to your application, you could use a framework, like Spring Boot or Quarkus. Both of these include easy options for embedding web servers.
But… frameworks require a little knowledge upfront. And frameworks add a lot of overhead, for something that can actually be solved without them.
So in this tutorial, we’ll see how to create a standalone Java application, with a main
method, which uses the Undertow web server to serve a simple “Hello, world!” message over HTTP.
You’ll create a simple, standalone command-line Java application, which is packaged as a very portable, executable JAR file.
But first, why?
Why though?
But first, why? Where would you use this?
I created this little app to scratch my own itch. Often, I need a simple example Java application, which I can use as part of a demo or teaching.
But maybe you want to do something else! Here are some other uses you might find for this little tutorial:
-
To run a minimal web server in Java, which returns a static web page.
-
To add an HTTP endpoint to your existing app, perhaps to return a status message or something else to clients.
-
To create an example Java app to use as part of something bigger: like testing a CI/CD pipeline, or perhaps to package into a Docker image and deploy to Kubernetes.
-
To see how to write a standalone Java application without using a framework like Spring Boot or Quarkus (yes, it’s possible!)
-
To dip your toe into the world of Java + Maven with a real project
-
To find out how small you can go…. this produces a self-contained (“fat-jar”) application that’s quite small – less than 3MB! (well, that’s small by Java standards 😉)
What is Undertow?
Undertow is a web server written in Java.
Undertow is an embedded web server for Java.
Like most Java projects, it’s an open source, community-driven project. You can check it out on GitHub.
How do you use it?
To add Undertow into your Java application, you import it as a library. Then you can use its API (its classes and methods) to create, configure, and start a web server.
Some application frameworks like Spring Boot can configure and start Undertow for you. But, in this tutorial, we’re going to do it manually.
So let’s get started!
Create the Java app and add Undertow
We’ll add Undertow to a Java project, and use it to serve a simple HTML page.
You don’t need to download Undertow yourself, as Maven will pull it as a dependency in during the build.
So now let’s get started and set up the project!
What we’ll create
-
A standalone Java application (without a framework)
-
Containing an embedded web server, which returns some static HTML as a string
What you’ll need
To follow this tutorial, you will need these tools in your toolbox:
-
Java 11+: You’ll need to be running JDK 11. This example uses lambda expressions, which were a new feature in Java 8.
-
Apache Maven: We’ll use Maven to download dependencies and compile the code, so make sure that it’s installed and accessible on your path.
Overview of the project
This project we’ll create has just 2 files:
-
pom.xml
-
Application.java
Your project tree will look something like this when finished:
.
├── pom.xml
└── src
└── main
└── java
└── com
└── tutorialworks
└── demos
└── hellorestjava
└── Application.java
Set up pom.xml
Let’s start by creating and configuring a pom.xml
in the root directory of the project.
This file tells Maven all of the dependencies that we need.
-
In your Java IDE, create a new Java Maven Project. It should create your POM file (
pom.xml
) for you. -
In the
<dependencies>
section of your POM file, add the dependencyio.undertow:undertow-core
.The latest version of Undertow at the time of writing is 2.2.17.Final.
<dependencies> <dependency> <groupId>io.undertow</groupId> <artifactId>undertow-core</artifactId> <version>2.2.17.Final</version> </dependency> </dependencies>
Set up Application.java
Next we need to add the main code.
Since this is a simple, standalone Java application, we’re going to create a main class – a class with a public static void main()
method – which will be the entry point to our program.
You can create your Application.java
in any package you like, but in this example I’ve located it at src/main/java/com/tutorialworks/simplehttp/Application.java
Let’s look at what we need to do.
Import Undertow and create the server
In the main
method, import packages from io.undertow
and create an instance of Undertow
. We use the builder()
to configure the host and port that the web server will listen on, and the payload that it should return.
Your code should look something like this:
package com.tutorialworks.simplehttp;
import io.undertow.Undertow;
import io.undertow.util.Headers;
/**
* Hello world!
* Returns a simple web page on port 8080.
*/
public class Application {
public static void main(String[] args) {
Undertow server = Undertow.builder()
// Set up the listener - you can change the port/host here
// 0.0.0.0 means "listen on ALL available addresses"
.addHttpListener(8080, "0.0.0.0")
.setHandler(exchange -> {
// Sets the return Content-Type to text/html
exchange.getResponseHeaders()
.put(Headers.CONTENT_TYPE, "text/html");
// Returns a hard-coded HTML document
exchange.getResponseSender()
.send("<html>" +
"<body>" +
"<h1>Hello, world!</h1>" +
"</body>" +
"</html>");
}).build();
// Boot the web server
server.start();
}
}
At this stage, the app is ready to run!
Run the app
We can now run the app with Maven:
mvn clean compile exec:java -Dexec.mainClass="com.tutorialworks.simplehttp.Application"
You can test the web server by going to http://localhost:8080 in your web browser.
Or, you can use a command line tool like curl
to test it:
$ curl http://localhost:8080
<html><body><h1>Hello, world!</h1></body></html>
To quit, just press Ctrl+C.
But, it would be better if we could package this app into a JAR file which we can share! So let’s do that next.
Package the app as an executable JAR
The modern way of packaging Java applications is to put them inside an executable JAR file.
This means that anyone with the JRE installed can take the JAR file, and just run it with the java -jar
command.
Configure Maven to build a JAR
In the POM file, configure Maven’s Assembly Plugin to produce the kind of package we want. We want to:
-
Build our fat JAR artifact (it’s actually called a “jar-with-dependencies”)
-
Specify our “main” class, so that the right method is called when the program starts.
To do this, add the following config inside the build
section of your POM file:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>com.tutorialworks.hellorestjava.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Now we’re ready to package and run.
Create the JAR and run it
Now, to compile the application and build the JAR file:
mvn clean package
What does this build?
This will build a “fat-jar” (a JAR containing your application, and all of its dependencies) inside the target/
folder:
$ ll target/java-http-server-undertow-1.0-SNAPSHOT-jar-with-dependencies.jar
-rw-r--r--. 1 tdonohue tdonohue 3.4M Apr 5 12:30 target/java-http-server-undertow-1.0-SNAPSHOT-jar-with-dependencies.jar
As you can see, the final jar on my laptop was only 3.4Mb!
And now to run the application, just run java -jar
with the relative path to the packaged JAR file:
java -jar target/java-http-server-undertow-1.0-SNAPSHOT-jar-with-dependencies.jar
Undertow should now be running on port 8080. You can use a web browser to go to http://localhost:8080 to see the output rendered as a web page.
Or, you can use a command-line HTTP client, like curl
, to fetch the web page:
$ curl http://localhost:8080
<html><body><h1>Hello, world!</h1></body></html>
To quit, just press Ctrl+C.
Summary
There you have it! We’ve created a simple Java application with an embedded web server, Undertow.
To grab the full code, click the button below:
Download the code on GitHub
What we’ve done:
-
Seen that Undertow can be used to create an embedded web server in a Java app
-
Created a standalone Java app with a main class, which creates and starts an instance of Undertow
-
Packaged the application into an executable JAR file
-
Tested the web server with curl, seeing the message returned!
Well done, and happy coding!