Working with Java Spark Framework

Creating a Rest based full stack application requires quite a bit of hands on knowledge of Back end services as well as Front end services. In this post, we are looking on Java micro web framework named Spark. We will build a rest based system where we can do stuff with User Data.

Requirements to get along

Spark is probably the easiest framework available to build a micro project. It removes the configuration hassles required while working with Spring or JSP etc. Lets get to the business. We would use Java 8 and Maven before starting with the application. To install Java 8 and Maven, you can follow the following steps -

Install Java 8

On Ubuntu
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java8-installer 
$ sudo apt-get install oracle-java8-set-default

On Mac, One can directly download JDK 8 from Oracle Website 

Check Java Version
$ java -version
java version "1.8.0_72"

Install Maven

$ sudo apt-get install maven

It will take a while to install.

Creating the Package

A Maven application requires creating certain configuration files. One such file is Pom.xml. Whether you use NetBeans or Eclipse , Pom.xml is automatically created. We will require to edit this file in order to get started. Spark is required to be included in our package, So add the following dependencies in pom.xml

<dependencies>
    <dependency>
        <groupId>com.sparkjava</groupId>
        <artifactId>spark-core</artifactId>
        <version>2.3</version>
    </dependency>
    <dependency>
        <groupId>com.sparkjava</groupId>
        <artifactId>spark-template-freemarker</artifactId>
        <version>2.3</version>
    </dependency>
    <dependency
        <groupId>com.fasterxml.jackson.core</groupId>
         <artifactId>jackson-core</artifactId>
         <version>2.5.1</version>
    </dependency>
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.5.1</version>
    </dependency>
</dependencies>
  • spark-core - Java Spark Framework
  • spark-template-freemarker - Free Marker Template for Front End
  • jackson-core - Basic JSON streaming API implementation

Folder Structure

The folder structure must look like below -

Main class

As all the MVC frameworks, Spark also requires writing Routes with get, put, post, delete methods. In our application, we want to first get import stuffs in our Driver Class.

import TemplateEngine.FreeMarkerEngine;
import java.io.IOException;
import static spark.Spark.*;
import spark.ModelAndView;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

public class MainClass {
    
    /**
     *  Entry Point
     * @param args
     */
    public static void main(String[] args) {
        MainClass s = new MainClass();
        s.init();
    }

Now we shall write the init() function to define our first route. Here is the code -

private void init() {
        get("/", (request, response) -> {
           Map<String, Object> viewObjects = new HashMap<String, Object>();
           viewObjects.put("title", "Welcome to Spark Project");
           viewObjects.put("templateName", "home.ftl");
           return new ModelAndView(viewObjects, "main.ftl");
        }, new FreeMarkerEngine());
}

Front End

As described, we now need to write the .ftl file which will contain our Html code. We shall use a Bootstrap starter template to get started.

<html>
    <head>
        <title>Spark Project</title>
        <link rel="stylesheet" href="css/bootstrap.min.css">
        <link rel="stylesheet" href="css/bootstrap-theme.min.css">
        <link rel="stylesheet" href="css/starter-template.css">
    </head>
    <body>

        <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="#"></a>
                </div>
                <div class="collapse navbar-collapse">
                    <ul class="nav navbar-nav">
                        <li class="active"><a href="/">Home</a></li>
                        <li><a href="createUser">Create User</a></li>
                        <li><a href="getAllUsers">Get All Users</a></li>
                        <li><a href="updateUser">Update User</a></li>
                        <li><a href="removeUser">Remove User</a></li>
                    </ul>
                </div><!--/.nav-collapse -->
            </div>
        </div>
        <script src="js/jquery.min.js"></script>
        <script src="js/bootstrap.min.js"></script>
        <div class="container">
            <#include "${templateName}">
        </div>
    </body>
</html>

Now create your home file.

<div class="starter-template">
   <h2>${title}</h2>
</div>

Running the Application

In order to run the application, we need to add certain code to our POM.XML file to let maven know what to do. Here is the code -

<name>SparkProject</name>
    <build>  
        <plugins>  
            <plugin>  
                <groupId>org.codehaus.mojo</groupId>  
                <artifactId>exec-maven-plugin</artifactId>  
                <version>1.2.1</version>  
                <executions>  
                    <execution>  
                    <phase>test</phase>  
                    <goals>  
                    <goal>java</goal>  
                    </goals>  
                    <configuration>  
                    <mainClass>Driver.MainClass</mainClass>  
                    </configuration>  
                    </execution>  
                </executions>  
            </plugin>  
        </plugins>  
    </build>

Now we can run -

mvn clean install
navigate to http://localhost:4567/

You should see the app running.

Rest Framework

We want to make our application restful, hence we need to deal with JSON for almost everything. I'll demonstrate on how we can delete a user. Check the below code -

get("/removeUser", (request, response) -> {
    Map<String, Object> viewObjects = new HashMap<String, Object>();
    viewObjects.put("templateName", "removeUser.ftl"); 
    viewObjects.put("users", toJSON(mod.sendUsersId()));
    response.status(200);
    return new ModelAndView(viewObjects, "main.ftl");
        }, new FreeMarkerEngine());

put("/removeUser/:id", (request, response) -> {
     String id = request.params(":id");
     if(mod.removeUser(id)) {
         response.status(200);
         return "User Removed";
     }
     else {
         response.status(404);
         return "No Such User Found";
     }
});

Here, we are using same url but with two different purpose. When you hit /removeUser/ , it renders the removeuser template, but when you create a put request on /removeUser/SomeID, that SomeID is checked in the database and if found, it is deleted else a simple message is sent back. See, how easily we can play with the response codes.
Click here to see the full code

Test Cases

Java Spark can easily be integrated with JUnit library. We shall write Unit test cases for our application. It’s simple because we do not need to mock anything related to Spark. We just need to mock our Model, which represents the way we access the database. However it has a simple interface and mocking it is straightforward. Let’s look at some examples.

import Model.Model;
import User.User;
import org.junit.Test;
import static org.junit.Assert.*;
import org.easymock.EasyMock;
import static org.easymock.EasyMock.*;

public class CreateUserTest {
    
    public CreateUserTest() {}
    
    @Test
    public void aUserIsNotValid() {
        User usr = new User();
        usr.setId("T12");
        usr.setFirstName("Test");
        usr.setAge(10);
        usr.setGender('X');
        usr.setLastName("Test");
        usr.setPhone("122");
        assertTrue(!usr.isValid());
    }
    
    @Test
    public void aUserIsCorrectlyCreated() {
        User usr = new User();
        usr.setId("T12");
        usr.setFirstName("Test");
        usr.setAge(10);
        usr.setGender('M');
        usr.setLastName("Test");
        usr.setPhone("1234567891");
        assertTrue(usr.isValid());
        
        Model model = EasyMock.createMock(Model.class);
        expect(model.createUser("T13", "Test","","Test",20,'M',"1234567891",12 
        )).andReturn(1);
    }

}

As you can see, it is so easy to check each and every unit of our code.

Conclusion

You can very well follow this GitHub link to all the code.
I hope this post gave a handful insight in writing a Full Stack rest based application with Java. Feel free to send comments and corrections as well as suggestions.