A lot of developers work on writing or debugging web applications daily. Sometimes that work involves writing our application’s backend and sometimes consuming other web resources, whether they are APIs or “normal” web pages. Other programming languages recognised the need for having a “quick and dirty” way of serving resources over HTTP(S) protocol during the development. Good people that developed JDK 18 gave us the opportunity to have that in Java too so we don’t have to look at node.js, Python or PHP developers with envy any more when they brag how simple it is to start serving resources in their languages. Let’s see the basic usage of Simple Web Server (SWS) in action!
Not only we can use SWS in Java, but we can do so in two flavours: as a new CLI tool
jwebserver, or programmatically as a proper API. This article covers the first usage. Programmatic one is covered in part 2.
Start SWS by typing
jwebserver in the shell/terminal. You should see output similar to this one:
1$ jwebserver 2Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::". 3Serving /Users/ivanmilosavljevic/Documents/swsdemo and subdirectories on 127.0.0.1 port 8000 4URL http://127.0.0.1:8000/
It informs us that it uses loopback interface and that it listens on port 8000. We can immediately visit
http://localhost:8000 in the browser and we’ll see a directory listing of a directory in which we’ve started SWS. Neat! At the same time, in the terminal we’ll see a log that contains information about the remote host address, date and time of a request, HTTP method, requested resource, version and status code:
1127.0.0.1 - - [30/Mar/2022:19:39:27 +0200] "GET / HTTP/1.1" 200 -
There are two things to note here. First one is, if we have an
index.html file in the directory in which we’ve started our server, then contents of that file will be served and not the directory listing. Second one is the visibility of the server - if you start it with
-b 0.0.0.0 it will bind to all interfaces and will be accessible from all hosts on your network. Depending on your use-case, this might be either a desired behaviour or a totally unacceptable one.
Of course, we can’t start another instance of SWS on the same port even if we start it from a different directory. If we try, SWS will greet us with:
1$ jwebserver 2Error: server config failed: java.net.BindException: Address already in use
The solution is to change the port it listens to by using
1$ jwebserver --port 8001 2Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::". 3Serving /Users/ivanmilosavljevic/Documents/anotherdir and subdirectories on 127.0.0.1 port 8001 4URL http://127.0.0.1:8001/
If we want to serve files from a directory different than the one we start SWS from, we must add a
1$ jwebserver --directory ~/tmp 2Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::". 3Serving /Users/ivanmilosavljevic/tmp and subdirectories on 127.0.0.1 port 8000 4URL http://127.0.0.1:8000/
Various options can be used together of course, like
jwebserver --port 8001 --directory ~/tmp. We can stop a running SWS with the usual
Ctrl+C or by sending it a SIGINT signal. We can see all supported options by typing
While the normal usage of SWS from command line is very straightforward, there are a few details you should take care of:
- it only serves single directory hierarchy and only static files
- only HTTP/1.1 is supported, no HTTPS, HTTP/2 or HTTP/3
- only GET and HEAD requests are served, everything else will receive either 405 or 501
- MIME types are automatically assigned
- symlinks and hidden files are not served
Dear fellow developer, thank you for reading this article about simple web server in Java. Until next time, TheJavaGuy saluts you!