Quick and Dirty Java Service Template

Dezember 25, 2017 1:04 pm Veröffentlicht von

To get a java service running, you don’t always need to start a tomcat and deploy a war file, as described in an earlier blog post. Even if tomcat gives you a number of benefits, such as user management and database connection handling, sometimes you do not need this and just want to start up a small http server to provide a bit of functionality.

The template contents

To get such projects started as fast as possible, I created the quick and dirty java service template, where I collected stuff I find most useful to implement a new java service:

It uses the grizzly http server to provide the web server, which makes starting an http server running java code as easy as executing a jar file.
Often, communication between a web page and a java backend works easiest by sending a JSON document. This is why we include the gson JSON parser in the template.
In addition to some java code, we will also package static content, such as html files or images to the jar package. All this can be accessed via the same URL after starting the jar file.

Checkout the service template at https://github.com/NautiluX/JavaServiceTemplate.

Start up

To build and run the server, we use mvn. So compilation and start can be done using the following two maven commands:

mvn clean install

mvn exec:java

now we can access our small server at localhost:5678.

Customize

Now for some more details to show you where to put server code and static content.
The project is set up using maven. That means all our java code can be found in src/main/java. When we start the server, by executing mvn exec:java, the class org.ntlx.server.Main will be executed, which creates the http server.

package org.ntlx.server;

import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
import com.sun.jersey.api.core.*;

import java.io.IOException;

import org.glassfish.grizzly.http.server.*;

public class Main {

  public static void main(String args[])
      throws IllegalArgumentException, NullPointerException, IOException {
    Main main = new Main();
    main.startServer();
  }

  public void startServer() throws IllegalArgumentException, NullPointerException, IOException {
    ResourceConfig rc = new PackagesResourceConfig(“org.ntlx.service”);
    HttpServer myServer = GrizzlyServerFactory.createHttpServer(“http://0.0.0.0:9876/calc/”, rc);
    HttpHandler httpHandler = new CLStaticHttpHandler(HttpServer.class.getClassLoader(), “/ui/”);
    myServer.getServerConfiguration().addHttpHandler(httpHandler, “/”);
    try {
      myServer.start();
      Thread.currentThread().join();
    } catch (Exception e) {
      System.err.println(e);
    } finally {
      myServer.stop();
    }
  }

}

The http server is listening on port 9876 and is searching for service endpoints in the package org.ntlx.service.

GET endpoint

To implement the code for our service, we take a look at the example implementation of the service template. We want our GET endpoint as heartbeat to check if the backend is up and running. Therefore we want it to just return
{
    “getCall”: “succeeded”
}
The code for this simple get endpoint can be found in the class org.ntlx.service.SumService in the function dummyGet:

package org.ntlx.service;

import com.google.gson.*;
import javax.ws.rs.*;

@Path(“sum”)
public class SumService {

  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public String dummyGet() {
    JsonObject result = new JsonObject();
    result.addProperty(“getCall”, “succeeded”);
    return result.toString();
  }

  …
}
We tell the http service, that we want requests that come in to the path /sum to be handled by this class. With the annotation @GET we tell it, that this function shall be called by GET http requests. With the @Produces annotation we get the http response header application/json. To create this simple json string, we use the Gson library.

POST/PUT/…

To create endpoints for other type of requests, we can do the same as for get. Lets have a look at the backend for our summing service, which should sum a list of numbers coming in as JSON.

  @POST
  @Produces(MediaType.APPLICATION_JSON)
  public String dummyPost(String body) {
    CalculatorInput input = new Gson().fromJson(body, CalculatorInput.class);
    JsonObject result = new JsonObject();
    result.addProperty(“result”, input.calculateSum());
    return result.toString();
  }

We tell the server we are listening for POST calls (the same could be done for POST, PUT, DELETE, etc.). We add a String parameter to the function, which will be filled up with the request body of the incoming POST call. To get the input, we again use GSON to instantiate an object of the CalculatorInput class, which executes our – very complex – workload in the function call calculateSum().

Static Content

Static content – like html files – must be located in the class path, so the http server can find it. That means we have to rebuild the jar file any time we want to change our static content. We told the http server where to search for it (/ui/) and where to place it (/). That means we can put our static content into the folder src/main/resources/ui, and they will be included in our jar file automatically and found by the http server under the path /. That’s why we are routed to the file created as src/main/resources/ui/index.html when we visit localhost:9876 after starting the server.
Stichwörter: , ,

Kategorisiert in: Allgemein

Dieser Artikel wurde verfasst von Manuel Dewald