JWebserver - Launch the Java Simple Web Server
Introducing jwebserver
jwebserver - a tool that offers a minimal HTTP server, serving a single directory hierarchy, and intended for prototyping, testing, and debugging.
Synopsis
jwebserver [options]
options
See options for the jwebserver
below.
The following options are available:
--bind-address addr
or —b addr
Specifies the address to bind to. The default address is 127.0.0.1
or ::1
(loopback). In case you need all interfaces, you can use -b 0.0.0.0
or -b ::
.
--directory dir
or —d dir
Specifies the directory to serve. The default value is current directory.
--help
or —h
Prints out a full help message.
--output level
or —o level
Specifies the output format and can be one of none | info | verbose
. The default value is info
.
--port port
or -p port
Specifies the port to listen on. The default port value is 8000.
--version
Prints out the abbreviated version string of the tool.
Description
jwebserver
is a JDK tool that provides a minimal HTTP server that you can use for prototyping, testing, and debugging. The tool serves only static files and looks into a single directory hierarchy over HTTP/1.1; dynamic content and other HTTP versions are not supported.
The module jdk.httpserver
contains jwebserver
, and can alternatively be started with java -m jdk.httpserver
because it is based on the web server implementation in the com.sun.net.httpserver
package.
The SimpleFileServer class offers a programmatic way to retrieve the server and its components for reuse and extension. Checkout the working with the Simple Web Server API section.
The requests method served are only idempotent HEAD
and GET
. If you will try any other requests, you will receive a 501 - Not Implemented
or a 405 - Not Allowed
response.
The tool maps GET requests to the directory being served, as follows:
- In case the requested resource is a file, its content is served.
- If the requested resource is a directory that contains an index file, the content of that index file is served.
- Otherwise, the response will contain the names of all files and subdirectories of the directory. Symbolic links and hidden files are not listed or served.
jwebserver
has MIME types automatically configured, using a built-in table. For example, .html
files are served as text/html
and .java
files are served as text/plain
.
Command Line Examples
jwebserver
can help you with:
Web development testing, when you need a local testing server to simulate a client-server set up.
jwebserver Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::". Serving /cwd and subdirectories on 127.0.0.1 port 8000 URL: http://127.0.0.1:8000/
Web-service or application testing, where you use static files as API stubs in a directory structure to mirror RESTful URLs and contain dummy data.
jwebserver -p 9000
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /youtube-jdk21 and subdirectories on 127.0.0.1 port 9000
URL http://127.0.0.1:9000/
127.0.0.1 - - [09/Jul/2023:13:02:05 +0200] "GET /api/activity.json HTTP/1.1" 200 -
127.0.0.1 - - [09/Jul/2023:13:02:06 +0200] "GET /api/activity.json HTTP/1.1" 200 -
- Informal browsing and sharing of files across systems to, e.g., search a directory on a remote server from your local machine.
jwebserver -b 0.0.0.0
Serving /work and subdirectories on 0.0.0.0 (all interfaces) port 8000
URL http://192.168.178.41:8000/
While the command-line tool is useful, you can also use the Simple Web Server (i.e., server, handler, and filter) with existing code via its API.
Working with the Simple Web Server API
In addition to the jwebserver
command-line tool, the Simple Web Server provides an API in order for you to programmatically create and customize the server and its components.
Earlier, you observed how the command jwebserver
serves the files of the current working directory. Yet, what you sometimes need that directory structure
to simulate expected response patterns and physically not preserve the mocks. You can achieve that behavior by using Google's Java in-memory file system Jimfs
to create in-memory resources
and serve them with the Simple Web Server:
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.UUID;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.sun.net.httpserver.SimpleFileServer;
import static com.sun.net.httpserver.SimpleFileServer.OutputLevel;
public class InMemoryFileServer {
private static final InetSocketAddress LOOPBACK_ADDR =
new InetSocketAddress(InetAddress.getLoopbackAddress(), 8080);
public static final String JSON_FILE_NAME = "thing.json";
public static final String DIR_PATH = "some/other";
public static void main( String[] args ) throws Exception {
Path root = createDirectoryHierarchy();
var server = SimpleFileServer.createFileServer(LOOPBACK_ADDR, root, OutputLevel.VERBOSE);
server.start();
System.out.printf("http://%s:%d%n", server.getAddress().getHostString(), server.getAddress().getPort());
}
private static Path createDirectoryHierarchy() throws IOException {
String json = """
{
"activity": "Go for a run",
"type": "recreational",
"participants": 1,
"distance": "%d km",
"key": "%s",
}
""";
FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
Path root = fs.getPath("/");
Path dir = Files.createDirectories(root.resolve(DIR_PATH));
Path filePath = fs.getPath(JSON_FILE_NAME);
Path innerMockFile = Files.createFile(dir.resolve(filePath));
Files.write(innerMockFile,json.formatted(12, UUID.randomUUID().toString()).getBytes(), StandardOpenOption.WRITE);
Path mockFile = Files.createFile(dir.getParent().resolve(filePath));
Files.write(mockFile,json.formatted(10, UUID.randomUUID().toString()).getBytes(), StandardOpenOption.WRITE);
return root;
}
}
Run the previous code snippet in the command line via:
$ java InMemoryFileServer.java
> http://127.0.0.1:8080
The example above serves a JSON response stored in server's memory, thus saving disk space while providing the necessary for API stubbing.
You can find another way to serve in memory assets in Christian Stein's article where he is implementing com.sun.net.httpserver.HttpHandler
to serve in-memory assets.
More programmatic examples on using the Simple Web Server API are available in Julia Boes' article on https://inside.java.
Useful Links
- In-memory HttpServer Handler: https://inside.java/2023/11/06/in-memory-http-server-handler/
- Working with the Simple Web Server: https://inside.java/2021/12/06/working-with-the-simple-web-server
More Learning
Last update: January 4, 2024