Home IT News Java’s Easy Net Server: Static HTTP servers made simple

Java’s Easy Net Server: Static HTTP servers made simple

0
Java’s Easy Net Server: Static HTTP servers made simple

[ad_1]

One of many handiest new options included within the Java 18 launch (March 2022) was the brand new Easy Net Server, which makes it simple to spin up and configure an HTTP file server. It additionally exposes an API that extends the present httpserver package deal for constructing easy use instances. 

The brand new Easy Net Server is a great tool that each Java developer ought to have of their bag of methods. Let’s test it out!

Java’s Easy Net Server on the command line

Java’s new jwebserver command makes it easy to run a primary internet server. It’s analogous to the favored SimpleHTTPServer software within the Python world.

Step one is to be sure to are working Java 18 or a later launch. Sort java --version to seek out out what launch you’re presently working. I like to recommend utilizing SDKMan to handle JDK installs. It is particularly helpful for juggling a number of variations.

jwebserver fundamentals

Essentially the most primary factor you are able to do with the Java Easy Net Server is to serve the present listing on port 8000. Simply enter the command proven in Itemizing 1.

Itemizing 1. No-arg internet server


$ jwebserver

Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /residence/matthewcarltyson and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/

From there, in case you go to your browser and go to localhost:8000, you may see an inventory of the file system, as proven in Determine 1.

Screenshot of a Simple Web Server instance. IDG
Determine 1. A Easy Net Server occasion working on port 8000.

Configuring the command line

There are a number of frequent stuff you would possibly must do to fine-tune Easy Net Server on the command line. For instance, you possibly can change the port, the tackle to bind to (the community interface to hear on), and the listing to serve. 

In Itemizing 2, you possibly can see hear on port 8080, on all interfaces, and within the /foo/bar listing.

Itemizing 2. Pay attention on port 8080, all interfaces, /foo/bar


$ jwebserver -b 0.0.0.0 -p 8081 -d /foo/bar

You will get an inventory of all of the choices with $ jwebserver -h.

As you possibly can see, the jwebserver command-line software makes it doable to serve static recordsdata utilizing the only doable syntax. Subsequent, we’ll check out the Easy Net Server API.

Utilizing Java’s Easy Net Server API

The Easy Net Server Javadoc is an efficient place to begin for studying concerning the API. The SimpleFileServer class exists within the com.solar.web.httpserver package deal. (This package deal additionally homes the older, lower-level APIs for constructing internet servers. The httpserver package deal extends that performance for easier necessities.) The jwebserver CLI software makes use of SimpleFileServer to do its work, and we will additionally use it programmatically.

The SimpleFileServer class solely handles GET and HTTP/1.1. We are able to do some attention-grabbing issues with it, although. For instance, this introduction to working with Easy Net Server suggests a means to make use of the Google Java in-memory file system challenge to pretend a file system for the handler.

We will use the thought of an in-memory file system to change the FileHandler in SimpleFileServer to really serve a digital file system from reminiscence. Then, we’ll use the httpserver package deal to deal with a POST so as to add a fake file to the fake file system.

Serve a digital file system from reminiscence

To start, let’s create a fast Maven challenge utilizing the next command:


$ mvn archetype:generate -DgroupId=.com.infoworld -DartifactId=jsws -DarchetypeArtifactId=maven-archetype-quickstart

Now, CD into the brand new /jsws listing. 

Set the compiler and supply variations to 18 within the pom.xml, as described right here.

Subsequent, add Google jimfs to the dependencies, as proven in Itemizing 3.

Itemizing 3. The Google Java in-memory file system dependency


<dependency>
  <groupId>com.google.jimfs</groupId>
  <artifactId>jimfs</artifactId>
  <model>1.3.0</model>
</dependency>

Now, we will modify the src/major/java/App.java file to serve a pretend file system. You may see the code to do that in Itemizing 4.

Itemizing 4. Serving the in-memory file system with SimpleFileServer


package deal com.infoworld;

import java.util.Record;
import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.web.InetAddress;
import java.web.InetSocketAddress;
import java.nio.file.FileSystem;
import java.nio.file.Information;
import java.nio.file.Path;
import com.google.frequent.jimfs.Configuration;
import com.google.frequent.jimfs.Jimfs;
import com.solar.web.httpserver.SimpleFileServer;

import static com.solar.web.httpserver.SimpleFileServer.OutputLevel;

public class Mem {
  personal static remaining InetSocketAddress ADDR =
    new InetSocketAddress("0.0.0.0", 8080);

  public static void major( String[] args ) throws Exception {
    Path root = createDirectoryHierarchy();
    var server = SimpleFileServer.createFileServer(ADDR, root, OutputLevel.VERBOSE);
    server.begin();
  }

  personal static Path createDirectoryHierarchy() throws IOException {
    FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
    Path root = fs.getPath("https://www.infoworld.com/");

    Information.createDirectories(root.resolve("check/test2"));

    Path foo = fs.getPath("/foo");
    Information.createDirectory(foo);

    Path good day = foo.resolve("good day.txt"); 
    Information.write(good day,  Record.of("good day", "world"), StandardCharsets.UTF_8);

    return root;
  }
}

The thought in Itemizing 4 is to simulate the usual native file system API utilizing Google’s open supply jimfs library, which implements the java.nio.file API however does all the things in-memory, like a digital file system. Utilizing the library, you possibly can outline your individual listing paths and recordsdata programmatically. So, we create our personal digital listing construction and hand that off to SimpleFileServer because the file handler.

We configure the SimpleFileServer class programmatically:


var server = SimpleFileServer.createFileServer(ADDR, root, OutputLevel.VERBOSE);

This accepts the web tackle to bind to, identical to we noticed from the command line. On this case, we go within the unspecified interface and port 8080. After that comes the file system root. For this instance, we’ll give it the Path object created by our createDirectoryHierarchy() methodology.

The createDirectoryHierarchy() methodology makes use of jimfs to construct a Path object: FileSystem fs = Jimfs.newFileSystem(Configuration.unix());. It then populates the Path with recordsdata and directories. The jimfs API for creating paths and recordsdata with content material just isn’t arduous to understand; for instance, we create one with Path good day = foo.resolve("good day.txt");. You should use many of the objects like they have been simply regular Java NIO paths.

Now, if we run this code and go to localhost:8080, you’ll see the listing itemizing and be capable of browse it and see file contents, identical to you’ll with a traditional file server.

Making a digital file

Let’s take this concept one step additional and add the flexibility to add a brand new file. We are able to use the com.solar.web.httpserver package deal to just accept a POST request that can add a brand new file to our in-memory file system. You may see this in Itemizing 5.

Itemizing 5. Importing a brand new file to the in-memory file system


package deal com.infoworld;

import com.solar.web.httpserver.HttpServer;
import com.solar.web.httpserver.HttpHandler;
import com.solar.web.httpserver.HttpExchange;

import java.io.IOException;
import java.io.OutputStream;

import java.web.InetSocketAddress;
import java.util.Record;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.Information;
import java.nio.file.Path;
import com.google.frequent.jimfs.Configuration;
import com.google.frequent.jimfs.Jimfs;
import com.solar.web.httpserver.SimpleFileServer;

import static com.solar.web.httpserver.SimpleFileServer.OutputLevel;

public class App {
  public static void major( String[] args ) throws Exception {
    // similar config...
    server.begin();

    // Create the HTTP server with the UploadHandler utilizing the identical 'root' path
    HttpServer httpServer = HttpServer.create(new InetSocketAddress("0.0.0.0", 8081), 0);
    httpServer.createContext("/add", new UploadHandler(root));
    httpServer.begin();
  }

  personal static Path createDirectoryHierarchy() throws IOException {
    // similar ...
  }

  // Handler to course of POST requests and add recordsdata
  static class UploadHandler implements HttpHandler {
    personal remaining Path root;

    public UploadHandler(Path root) {
      this.root = root;
    }

    @Override
       public void deal with(HttpExchange trade) throws IOException {
       if ("POST".equalsIgnoreCase(trade.getRequestMethod())) {
         String filename = trade.getRequestHeaders().getFirst("filename");

         if (filename != null) {
           Path newFilePath = root.resolve(filename);
          strive (OutputStream os = Information.newOutputStream(newFilePath)) {
            trade.getRequestBody().transferTo(os);
          }
          String response = "File uploaded efficiently: " + filename;
          trade.sendResponseHeaders(200, response.getBytes(StandardCharsets.UTF_8).size);
          strive (OutputStream os = trade.getResponseBody()) {              
            os.write(response.getBytes(StandardCharsets.UTF_8));
          }
        } else {
          trade.sendResponseHeaders(400, -1); // Unhealthy Request
        }
      } else {
        trade.sendResponseHeaders(405, -1); // Methodology Not Allowed
      }
    }
  }
}

In Itemizing 5, we preserve many of the class the identical, however at an HttpServer occasion listening on port 8081. That is configured with our customized uploadHandler, which takes the uploaded knowledge and makes use of it to write down a brand new file to the basis path that we created in createDirectoryHierarchy.

To check this out, we will run the entire server cluster with:


$ mvn clear set up exec:java -Dexec.mainClass="com.infoworld.Mem"

You may push a brand new file to the server with a CURL request just like the one in Itemizing 6.

Itemizing 6. CURL POST a file


$ contact file.txt
$ curl -X POST -H "filename: file.txt" -d "@file.txt" http://localhost:8081/add

File uploaded efficiently: file.txt

While you reload the localhost:8080/ file listings, you’ll see the brand new file.txt and you’ll click on it and consider its contents.

A quick, easy, and versatile internet server

Easy Net Server is a welcome addition to the Java toolset. Not solely does it make internet hosting recordsdata quite simple with the CLI, it introduces some attention-grabbing prospects with its API, particularly when used along side the decrease stage HttpServer API.

To be taught extra, take a look at these extra assets:

Copyright © 2023 IDG Communications, Inc.

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here