JDK 18: Simple Web Server
Published: 2022-01-22 10:00:01

![JDK](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5deeds2qu02ciardid0e.png)

JDK 18 version is all set to release in **March 2022** and will be coming with 9 new features (with some enhancement features from the previous versions).

- 400: UTF-8 by Default
- **408: Simple Web Server**
- 413: Code Snippets in Java API Documentation
- 416: Reimplement Core Reflection with Method Handles
- 417: Vector API (Third Incubator)
- 418: Internet-Address Resolution SPI
- 419: Foreign Function & Memory API (Second Incubator)
- 420: Pattern Matching for switch (Second Preview)
- 421: Deprecate Finalization for Removal


JDK 18 will be packaged with a **NEW** command line (i.e. **jwebserver**) tool to start a minimal web server that serves static files only. As of now (even no confirmations about future plans), there is No CGI or servlet-like functionality available with **jwebserver**. This tool will be useful for prototyping, ad-hoc coding, and testing purposes, particularly in educational contexts.

The Simple Web Server is a minimal HTTP server for serving a single directory hierarchy and can be used via the dedicated command-line tool **jwebserver** or programmatically via its API.


### Installation of JDK 18 EA builds (as of now only EA builds are available):
One can download the JDK 18 Early-Access Builds from [jdk.java.net](https://jdk.java.net/18/)

Or Another way to manage the JDK versions would be using [SDKMAN](https://sdkman.io/install). Take a look at the [usage page](https://sdkman.io/usage) to setup desired java version.

```{bash}
$ curl -s "https://get.sdkman.io" | bash
$ sdk install java 18.ea.31-open
```

### A. Using **_jwebserver_** Command Line:
After installing JDK 18 we are set to use jwebserver command line utility. 
By default, the server runs in the foreground and binds to the loopback address and port 8000. Also, if the directory (-d option) is not specified, files are served from the current directory.

```{bash}
$ 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.
```

Let’s serve a directory containing HTML content using jwebserver, and see how this utility made it easier.

1) Create a directory and add an index.html file in the directory with some html content.
```{bash}
$ mkdir jdk18-webserver
$ cd jdk18-webserver
$ echo "<h1>Hello World from JWebServer</h1>" > index.html
```
2) Run the jwebserver 
```{bash}
$ jwebserver -p 8080 -d /Users/home/jdk18-webserver

Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /Users/home/jdk18-jwebserver and subdirectories on 127.0.0.1 port 8080
URL http://127.0.0.1:8080/
```

### B. Using APIs:

While the command-line tool is useful, what if one wants to use the components of the Simple Web Server (i.e. server, handler, and filter) with existing code, or further customize the behavior of the handler?

This Simple Webserver API is based on the web server implementation in the `com.sun.net.httpserver` package that has been included in the JDK since `2006`. The package is officially supported and extended with APIs to simplify server creation and enhance request handling.

The SimpleFileServer class supports the creation of a file server, a file-server handler, and an output filter:

```{java}
package com.sun.net.httpserver;

public final class SimpleFileServer {
    public static HttpServer createFileServer(InetSocketAddress addr,
                                              Path rootDirectory,
                                              OutputLevel outputLevel) {...}
    public static HttpHandler createFileHandler(Path rootDirectory) {...}
    public static Filter createOutputFilter(OutputStream out,
                                            OutputLevel outputLevel) {...}
    ...
}
```

Let's create a server instance using jshell.
1) Define the server configurations.
```{java}
jshell> import com.sun.net.httpserver.SimpleFileServer;
jshell> var dir = "/Users/home/jdk18-webserver";
jshell> var PORT = 8080;
jshell> var server = SimpleFileServer.createFileServer(new InetSocketAddress(PORT),
            Path.of(dir), SimpleFileServer.OutputLevel.VERBOSE);
```

2) Starting the web server: static method `SimpleFileServer.createFileServer()` returns the instance of `com.sun.net.httpserver.HttpServer` which can be used to start or stop the server.

```{java}
jshell> server.start()
```
Logs generated on hitting the URL (http://127.0.0.1:8080) -
```{log}
jshell> 127.0.0.1 - - "GET / HTTP/1.1" 200 -
Resource requested: /Users/home/jdk18-jwebserver
> Accept-encoding: gzip, deflate, br
> Accept: text/html,application/...
> Sec-fetch-dest: document
> Sec-fetch-user: ?1
> Connection: keep-alive
> Sec-fetch-site: none
> Host: 127.0.0.1:8080
> Accept-language: en-GB,en;q=0.9,en-US;q=0.8
...
...
...
< Content-type: text/html
< Content-length: 36
```
3) Stopping the server: The HttpServer instance has stop method which accepts delay in seconds as Integer argument. The method will then block until all current exchange handlers have completed or else when approximately delay seconds have elapsed (whichever happens sooner).

```{java}
// server.stop(delay: Integer)
jshell> server.stop(0)
```

### Thoughts
As Intended, The Simple Web Server is not so feature-rich, but it is an appropriate tool to get your static contents served without handling the hassles of writing a huge chunk of code for such a small work to be done. To learn more about jwebserver, check out the official [JEP 408](https://openjdk.java.net/jeps/408) document...

Please share your thoughts in the comments!