HTTP Server

The javaxt-server library is used to create high performance web applications without all the weight and complexity of a traditional J2EE app server. This library has been used in production for several years to host websites, develop lightweight desktop applications, implement distributed processing architectures, run web map servers, and much, much more.

Download javaxt-server
Current Version: 4.1.2
Release Date: 9/14/2022
File Size: 2,612 KB
File Format: Zip
Includes: Jar File and Source Code

Key Features

  • Blazing fast performance
    • Over 10,000 requests per second!
    • Non-blocking sockets and IO streams
  • SSL support
  • Persistent connections (e.g. HTTP Keep-Alive)
  • GZIP compression
  • Chunked transfer encoding
  • Multiple socket listeners
  • HTTP session management
  • Web sockets
  • Form processor
  • CGI Support

Basic Usage

To implement a web server, you need to create a class that extends the HttpServlet class and has a processRequest() method. The HttpServlet is then passed to the Server constructor, along with an address/port to bind to, and the total number of threads used to process client requests. Example:

    int port = 9080;
    int numThreads = 50;

    new javaxt.http.Server(port, numThreads, new HttpServlet() {

        public void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, java.io.IOException {

            response.write("Hello, the time is now " + new java.util.Date());
        }

    }).start();

In this simple example, if you navagate to http://localhost:9080 the server will return a simple response with the current time.

Processing Requests

The processRequest() method of the HttpServlet is used to read HTTP requests and send a response to the client. The method accepts a HttpServletRequest and a HttpServletResponse. The HttpServletRequest contains all the information about the HTTP request (e.g. request method, URL, incoming IP address, browser info, etc). The HttpServletResponse class is used to send responses to the client.

Routing Requests

Below is a slightly more sophisticated implementation of a processRequest() method. In this example, the HttpServlet is used to serve up both static and dynamic content. If the requested URL starts with "calculator" the server will return dynamic content. Otherwise, the server will return a file from disk.

package com.example;
import javaxt.http.servlet.*;

public class TestServlet extends HttpServlet {

  //Path to static files
    private java.io.File webDir;


  //Constructor
    public TestServlet(java.io.File webDir){
        if (webDir==null || !webDir.exists() || !webDir.isDirectory()){ 
            throw new IllegalArgumentException();
        }
        this.webDir = webDir;
    }


  //Request Processor
    public void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, java.io.IOException {


      //Get requested path
        String path = request.getURL().getPath();
        if (path.length()>1 && path.startsWith("/")) path = path.substring(1);


      //Peel off the first part of the path. We'll use this to determine whether to serve
      //static or dynamic content.
        String service = path.toLowerCase();
        if (service.contains("/")) service = service.substring(0, service.indexOf("/"));


      //If the path start with "calculator", return some dynamic content
        if (service.equalsIgnoreCase("calculator")){

            String op = request.getParameter("op");
            if (op.equals("add")){
                Integer a = Integer.parseInt(request.getParameter("a"));
                Integer b = Integer.parseInt(request.getParameter("b"));
                response.write((a+b)+"");
            }
            else{
                response.sendError(501, "Not Implemented");
            }

        }
        else { //Return file

          //Construct a physical file path using the url
            java.io.File file = new java.io.File(webDir, path);


          //Return response
            if (!file.exists() || file.isDirectory()){ 

              //File doesn't exist, return an error
                response.setStatus(404);
            }
            else{ 

              //Dump the file content to the servlet output stream
                response.write(file, getContentType(file), true);
            }
        }
    }


  //Function used to guess a mime type from the file extension
    private String getContentType(java.io.File file){

        String fileName = file.getName();
        String fileExtension = "";
        if (fileName.contains(".")){
            fileExtension = fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();
        }

        if (fileExtension.equals("css"))  return "text/css";
        if (fileExtension.equals("html")) return "text/html";
        if (fileExtension.equals("js"))   return "text/javascript";
        if (fileExtension.equals("txt"))  return "text/plain";

        return "application/octet-stream";
    }
}

If the requested URL starts with "calculator", we will parse the query string to determine an operation to perform (e.g. http://localhost:9080/calculator?op=add&a=1&b=2). Otherwise, the server will return a file from disk (e.g. http://localhost:9080/images/test.jpg).

To run this example, instantiate the servlet using a path to a web directory and start the server like this:

java.io.File webDir = new java.io.File("/temp/webroot/");
new javaxt.http.Server(port, numThreads, new TestServlet(webDir)).start();

More Examples

History

The javaxt-server library was originally developed in the late 2000s as a simple, lightweight, embeddable, pocket server. It relied on a simple threading model to process raw socket requests. This 1.x series of the javaxt-server worked really well and was really fast. Sometime around 2012, I was asked to add SSL support for a client which was a really interesting challenge and yielded the 2.x versions of the library. However, sometime in 2017 I started running into some really odd SSL issues that I had a hard time debugging. I ended up swapping out the core HTTP and SSL engine with an stripped down version of Jetty. Since then, the library has been solid as a rock. The server has performed flawlessly and has run continuously at multiple client sites for many years.

Java Compatibility

The javaxt-server library is best used with Java 11 and up. The library has no dependencies.

Maven Support

If you're a Maven user, you can configure your pom.xml to pull releases directly from this site. To add javaxt-server to your project, simply add this site to your list of repositories and add a dependency. XML snippits below. See the downloads page for more information.
Add Maven Repository
  <repositories>
    <repository>
      <id>javaxt.com</id>
      <url>https://www.javaxt.com/maven</url>
    </repository>
  </repositories>
Add Maven Dependency
  <dependencies>
    <dependency>
      <groupId>javaxt</groupId>
      <artifactId>javaxt-server</artifactId>
      <version>4.1.2</version>
    </dependency>
  </dependencies>