Tuesday, May 31, 2022

Java 18: Simple Web Server

Java 18 offers an out-of-the-box simple web server (jwebserver) that serves static files only (no servlet-like functionality or CGI). This tool is useful for prototyping, ad hoc coding, and testing.

To start the server, simply run:

$ jwebserver
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving C:\Users\fahd\blog and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/

127.0.0.1 - - [31/May/2022:10:37:31 +0100] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2022:10:37:33 +0100] "GET /2022/ HTTP/1.1" 200 -

By default, the server binds to localhost:8000 and serves the current working directory. Every request is logged to the console.

You can change the bind address, port number, directory and logging format using the options shown below:

$ jwebserver --help
Usage: jwebserver [-b bind address] [-p port] [-d directory]
                  [-o none|info|verbose] [-h to show options]
                  [-version to show version information]
Options:
-b, --bind-address    - Address to bind to. Default: 127.0.0.1 (loopback).
                        For all interfaces use "-b 0.0.0.0" or "-b ::".
-d, --directory       - Directory to serve. Default: current directory.
-o, --output          - Output format. none|info|verbose. Default: info.
-p, --port            - Port to listen on. Default: 8000.
-h, -?, --help        - Prints this help message and exits.
-version, --version   - Prints version information and exits.
To stop the server, press Ctrl + C.

To programmatically start the web server from within a java application, you can use the SimpleFileServer.createFileServer method:

import java.net.InetSocketAddress;
import java.nio.file.Path;

import com.sun.net.httpserver.SimpleFileServer;
import com.sun.net.httpserver.SimpleFileServer.OutputLevel;

final var server = SimpleFileServer.createFileServer(
                       new InetSocketAddress(8080), 
                       Path.of("C:\\Users\\fahd\\blog"),
                       OutputLevel.VERBOSE);
server.start();

Alternatively, use HttpServer.create if you wish to pass in your own HTTP handler and filter:

import java.net.InetSocketAddress;
import java.nio.file.Path;

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.SimpleFileServer;
import com.sun.net.httpserver.SimpleFileServer.OutputLevel;

final var server = HttpServer.create(
              new InetSocketAddress(8000),
              10,
              "/context/",
              SimpleFileServer.createFileHandler(Path.of("C:\\Users\\fahd\\blog")),
              SimpleFileServer.createOutputFilter(System.out, OutputLevel.INFO));
server.start();