Intro to Java's Simple Web Server

Blog

HomeHome / Blog / Intro to Java's Simple Web Server

Sep 02, 2023

Intro to Java's Simple Web Server

By Matthew Tyson Software Architect, InfoWorld | One of the most handy new features included in the Java 18 release (March 2022) was the new Simple Web Server, which makes it easy to spin up and

By Matthew Tyson

Software Architect, InfoWorld |

One of the most handy new features included in the Java 18 release (March 2022) was the new Simple Web Server, which makes it easy to spin up and configure an HTTP file server. It also exposes an API that extends the existing httpserver package for building simple use cases. The new Simple Web Server is a useful tool that every Java developer should have in their bag of tricks. Let's check it out!

Java’s new jwebserver command makes it simple to run a basic web server. It is analogous to the popular SimpleHTTPServer tool in the Python world.

The first step is to make sure you are running Java 18 or a later release. Type java --version to find out what release you are currently running. I recommend using SDKMan to manage JDK installs. It's especially useful for juggling multiple versions.

The most basic thing you can do with the Java Simple Web Server is to serve the current directory on port 8000. Just enter the command shown in Listing 1.

From there, if you go to your browser and visit localhost:8000, you’ll see a listing of the file system, as shown in Figure 1.

There are several common things you might need to do to fine-tune Simple Web Server on the command-line. For example, you can change the port, the address to bind to (the network interface to listen on), and the directory to serve.

In Listing 2, you can see how to listen on port 8080, on all interfaces, and in the /foo/bar directory.

As you can see, the jwebserver command-line tool makes it possible to serve static files using the simplest possible syntax. Next, we'll take a look at the Simple Web Server API.

The Simple Web Server Javadoc is a good starting point for learning about the API. The SimpleFileServer class exists in the com.sun.net.httpserver package. (This package also houses the older, more low-level APIs for building web servers. The httpserver package extends that functionality for simpler requirements.) The jwebserver CLI tool uses SimpleFileServer to do its work, and we can also use it programmatically.

The SimpleFileServer class only handles GET and HTTP/1.1. We can do some interesting things with it, though. For example, this introduction to working with Simple Web Server suggests a way to use the Google Java in-memory file system project to fake a file system for the handler.

We’re going to use the idea of an in-memory file system to modify the FileHandler in SimpleFileServer to actually serve a virtual file system from memory. Then, we'll use the httpserver package to handle a POST to add a faux file to the faux file system.

To begin, let’s create a quick Maven project using the following command:

Now, CD into the new /jsws directory.

Set the compiler and source versions to 18 in the pom.xml, as described here.

Next, add Google jimfs to the dependencies, as shown in Listing 3.

Now, we can modify the src/main/java/App.java file to serve a fake file system. You can see the code to do this in Listing 4.

The idea in Listing 4 is to simulate the standard local file system API using Google's open source jimfs library, which implements the java.nio.file API but does everything in-memory, like a virtual file system. Using the library, you can define your own directory paths and files programmatically. So, we create our own virtual directory structure and hand that off to SimpleFileServer as the file handler.

We configure the SimpleFileServer class programmatically:

This accepts the internet address to bind to, just like we saw from the command line. In this case, we pass in the unspecified interface and port 8080. After that comes the file system root. For this example, we'll give it the Path object created by our createDirectoryHierarchy() method.

The createDirectoryHierarchy() method uses jimfs to build a Path object: FileSystem fs = Jimfs.newFileSystem(Configuration.unix());. It then populates the Path with files and directories. The jimfs API for creating paths and files with content is not hard to grasp; for example, we create one with Path hello = foo.resolve("hello.txt");. You can use most of the objects like they were just normal Java NIO paths.

Now, if we run this code and visit localhost:8080, you’ll see the directory listing and be able to browse it and see file contents, just like you would with a normal file server.

Let’s take this idea one step further and add the ability to upload a new file. We can use the com.sun.net.httpserver package to accept a POST request that will upload a new file to our in-memory file system. You can see this in Listing 5.

In Listing 5, we keep most of the class the same, but at an HttpServer instance listening on port 8081. This is configured with our custom uploadHandler, which takes the uploaded data and uses it to write a new file to the root path that we created in createDirectoryHierarchy.

To test this out, we can run the whole server cluster with:

You can push a new file to the server with a CURL request like the one in Listing 6.

When you reload the localhost:8080/ file listings, you’ll see the new file.txt and you can click it and view its contents.

Simple Web Server is a welcome addition to the Java toolset. Not only does it make hosting files very simple with the CLI, it introduces some interesting possibilities with its API, especially when used in conjunction with the lower level HttpServer API.

To learn more, check out these additional resources:

Next read this:

Matthew Tyson is a founder of Dark Horse Group, Inc. He believes in people-first technology. When not playing guitar, Matt explores the backcountry and the philosophical hinterlands. He has written for JavaWorld and InfoWorld since 2007.

Copyright © 2023 IDG Communications, Inc.

Next read this: