I am the captain of my own starship.

Fly with me, "boldly go where no man has gone before!"

Using Jetty Web Server to Serve Static Web Content

This post is originally published on www.CodeProject.com.


For this article, I just want to discuss two different approaches of using Jetty, the J2EE web server to serve/deliver static web content to the users. Static web content are file like web page files (*.html), JavaScript files (*.js), non-text web resources like text files (*.txt), image files (*.jpg. *.gif, *.png, etc). This is an easy technical problem, for most of the times, one can just open these files in web browsers. If this does not satisfy one's need, one can also use a HTTP web server like Apache Http Web Server, or Ngnix. Alternatively, one can use Python, Ruby on Rail or Node JS to start a light weigh web server.

So what is the point of using Jetty Web Server to simply deliver static web content? The point is convenience. I have been doing a lot of JavaScript related work, and I need to have a simple web server that can allow an end user to open a web page, and test the UI interactions. For me, spending time on unfamiliar approaches is just wasting time. So I did some digging, and I discovered two different ways I can start up a web server using Jetty. It turned out that both approaches are quite easy. I was thrilled.

Approach #1

This approach requires Jetty 9.3.x and up. All you need to do is put an XML file into the webapps directory, then start Jetty Web Server up. This XML file will direct the Jetty Web Server to a directory where static web content can be found and served to end user who request for them.

Here is a sample XML file. I call it junk.xml. You can name it anything you want. The name should not matter much. And you can have as many of these XML files as you want, each can point to folders that have static web contents. When Jetty Web Server starts, it wil find these files and create virtual web applications that just delivers any static web contents on demand:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
  <Set name="contextPath">/monkey</Set>
  <Set name="handler">
    <New class="org.eclipse.jetty.server.handler.ResourceHandler">
      <Set name="resourceBase">c:/DevJunk/monkey</Set>
      <Set name="directoriesListed">false</Set>

The content of this xml file is as the following:

  • contextPath: it is the web application context. Here is an example: http://localhost:8080/monkey, the part named "moneky" is what is specified here.
  • handler: This specifies the request handler. For delivering static web content, the handler is used here is called: org.eclipse.jetty.server.handler.ResourceHandler.
  • The handler need to have a base directory to find all the static web content, that is what "resourceBase" is used here. And it specifies C:\DevJunk\monkey as the base folder.
  • The next one ("directoriesListed") specifies whether or not to list the directory content when the url path this handler interpret to be a directory. For security reason, I would always set this to false. But this is used purely for testing, so it does not matter what you set. To test this, you can browse http://localhost:8080/monkey/ and if you set it true, you will see the content of the directory.

The following is how you test the above configuration:

  1. Assuming you put the downloaded the Jetty Web Server (Jetty 9.3.x and up), which comes as a zip archive. You unzip it and put in an arbitrary location.
  2. Inside this folder, there is the webapps folder. Put the XML file into this folder (webapps).
  3. Then create the folder structure C:\DevJunk\monkey, and in C:\DevJunk\monkey, put a text file called junk5.txt in it.
  4. Start up the Jetty Server by this command in the base folder of the Jetty Web Server.
  5. Use a web browser and navigate to http://localhost:8080/monkey/junk5.txt. If you put some text content in the file junk5.txt. You can see the content in the web browser.

To start up the Jetty Web Server, the command is:

java -jar start.jar

As you can see, this is pretty easy to do. Ccreate one configuration file, setup the static web content folders and files, and start up the web server. And it is ready for testing and playing. This, however, only works if you have Java 1.8 and Jetty 9.3.x and above. What if you don't have Java 1.8, but only the lower version? In the next section, I am going to provide a great alternative.

Approach #2

Here are the steps to accomplish this:

  1. Assuming you put the downloaded the Jetty Web Server (any version f Jetty would do), which comes as a zip archive. You unzip it and put in an arbitrary location.
  2. Assuming you put the Jetty Web Server at C:\Jetty\. In this folder, find sub folder webapps. In it, create a sub folder with any name you like. For demo purposes, I will call this sub folder "monkey". So I have C:\Jetty\webapps\monkey.
  3. In this subfolder in webapps (a.k.a "monkey"), create another sub folder called WEB-INF.
  4. In this WEB-INF folder, put in a file called web.xml.

Before I continue, I like to show the content of the web.xml:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"

What I have done so far is creating a web based application, a very simple one. The web application is called "monkey" which is just the folder name. For J2EE web server, when it starts up and find directories inside the web deployment folder (which in this case is the webapps in Jetty), it would look for a sub folder called WEB-INF, and in it find the web.xml. This web.xml would define how http request should be routed and handled. The above web.xml configuration would receive any http request that has the url prefix of http://localhost:8080/monkey. This is not configured by web.xml, by default the folder name "monkey" determines the sub url path, which is also called a context.

You might ask, here is no Java code, how does it handle the http request? Any J2EE container, like Jetty or Tomcat or etc, had a DefaultHandler that could deliver static web contents to the user by http requests. That is what this web.xml is specifying. In this web.xml, there is the section "servlet-mapping". The element "servlet-name" is set to default. This is telling the J2EE Web Server that for this application "monkey", the DefaultHandler will be used to handle the http requests. The next element is specifying what the url sub path it will match to route the http request to this web app. The url pattern is set as "/*", meaning any request under the name money (i.e. http://localhost:8080/monkey/*) would be routed to this web application called monkey.

So where do you put the static content? In the base directory of this "monkey" web application (i.e. c:\Jetty\webapps\monkey), I would put a text file called junk.txt. Then I would start up the Jetty Web Server, and use web browser to navigate to http://localhost:8080/monkey/junk.txt. If I did everything correctly, I would see the text content displayed in the web browser. You can try this too.

Just one more thing, if your static web content are structured in a complex folder hierarchy, when you put them in the base directory of this web application, the request url would use the same folder hierarchy to specify what static web file to pull. For example, you have a html file stored as c:\Jetty\webapps\monkey\testwebpages\sales\order\test.html. To request thisfile to be displayed, you can use this url: http://localhost:8080/monkey/testwebpages/sales/order/test.html. Just play with it and you will get the point. This is all needed to serve static web contents.

A final note on this, this approach can be used in any J2EE based web server. You just need to find the folder for the web application deployments, the equivalent of webapps in Jetty.

Points of Interest

Just to summarize. The purpose that I created this tutorial is to show how easy it is to use Jetty Web Server to serve static web content. This will be a great way for testing JavaScript powered web pages. With many of the modern web application frameworks, creating a web application can be done with only HTML and JavaScript. Most of these frameworks uses ajax for a variety of functionality. And without a web server to host such an application, the web browser sometimes won't execute any of the ajax based functionality. You can easily see this by using the Chrome browser.

Instead of using any unfamiliar technologies, anyone who has exeperience with J2EE web servers should be able to use the second approach and run static web content like a real web site. I prefer Jetty Web Server because it is small, and the latest version also support the first approach, which simplifies the configure a little. But either way, one can easily serve static web content as a mean for local testing. I hope this is useful for anyone who needed it.