Home » Core Java » Real-time Applications with AngularJS and Java – Part 1

About Sylvain Cloutier

Sylvain Cloutier
Sylvain has been programming in Java for the past 5 years, mainly in the aerospace industry, as a lead developer of complex web based aircraft wiring systems. He is also one of the organizers of the Java User Group of Quebec City and currently works as a Java developer consultant at CGI.

Real-time Applications with AngularJS and Java – Part 1

1. Introduction

In 2015, is it still acceptable to develop web applications in which we have to hit F5 to actualize the page content? The answer is simple: Of course yes! But still, we can offer our users a better overall experience. I could ask myself: How comes Twitter or Facebook are able to notify me when I have new interactions or messages, but the software I use at my job is not? This is where the real-time applications get on stage.

This article is the first of a series of three in which I want to introduce you the basic concepts behind real-time applications in Java with simple examples.  In this first article, I will demonstrate how GMail, Facebook, Twitter and many other websites have implemented real-time notifications using the periodic refresh design pattern.

angularjs_small

AngularJS Programming Cookbook

In this ebook, we provide a compilation of AngularJS based examples that will help you kick-start your own web projects. We cover a wide range of topics, from Single Page Apps and Routing, to Data Binding and JSON Fetching. With our straightforward tutorials, you will be able to get your own projects up and running in minimum time. Download the cookbook by joining the Web Code Geeks Newsletter.

In this example, I will be showing you how real-time updates can be useful in a system where the users execute tasks that take time to run (import of CSV files into the system, copy of files from server to server, batch update in the database, etc.). AngularJS will be used in the front end to implement the Periodic Refresh pattern. Spring and Jackson will be used together to create a RESTful JSON Web Service answering the AJAX request made by Angular. If you do not know about AngularJS or Spring MVC, I would suggest you read tutorials before. Here is a screenshot of the end result:

Figure 1. Screenshot of the end result

Figure 1. Screenshot of the end result

2. The Periodic Refresh AJAX pattern

The Periodic Refresh pattern or polling is the simplest way of creating a real-time application. Basically, a JavaScript function periodically creates an XMLHttpRequest that is sent to the server. This request asks the server for updated information, then the view is actualized if necessary.

Figure 2. ClientServerBlank_PeriodicRefresh

Figure 2. ClientServerBlank_PeriodicRefresh

You can easily see this pattern in action in your Twitter feed. In any modern browser, hit F12, go to the Network tab and filter the requests so only XHR are displayed. Every 10 seconds or so, a new request is sent to the server asking for an update regarding new tweets. If there is any, a notification is displayed.

Figure 3. TwitterPeriodicRefresh

Figure 3. TwitterPeriodicRefresh

3. RESTful JSON Java Back-end

3.1. Maven dependencies

In order to create a simple REST web service that will accept and answer JSON objects, you have to include Spring MVC and Jackson. Your pom.xml file should contain the following dependencies:

pom.xml

 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>4.2.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>4.2.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
</dependency>

3.2. The Task object

Then, we want to create our Task object that will be used in the web service. This Task object has a duration in milliseconds and a status that can either be IDLE, RUNNING or SUCCESS.

Task.java

public class Task {
  private TaskStatus status = TaskStatus.IDLE;
  private long duration;

  // Getters and Setters...

  public void decrementDuration() {
    this.duration--;
  }

  public boolean isRunning() {
    return this.status.equals(TaskStatus.RUNNING);
  }
  
  public String getName() {
    return this.toString();
  }

  public void start() {
    this.status = TaskStatus.RUNNING;
  }
}

3.3. The TaskExecutor

Those Task objects, once instanciated, will be managed by a class called TaskExecutor. This class is a Spring Singleton that holds the tasks submitted by all users. Once it’s instanciated, it starts a thread that loops through the running tasks in the tasks pool and decrement their duration. When the duration gets to zero, the status is set to SUCCESS:

TaskExecutor.java

package com.javacodegeeks.examples.realtimeapp.part1.services;

import java.util.LinkedList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.javacodegeeks.examples.realtimeapp.part1.domain.Task;
import com.javacodegeeks.examples.realtimeapp.part1.domain.TaskStatus;

@Component
@Scope("singleton")
public class TaskExecutor {
  private List pool = new LinkedList<>();
  
  @PostConstruct
  public void initialize() {
    Runnable taskPoolConsumer = () -> {
      while (true) {
        try {
          this.pool.stream()
              .filter(task -> task.isRunning() && task.getDuration() > 0)
              .forEach(task -> task.decrementDuration());
          
          this.pool.stream()
            .filter(task -> task.isRunning() && task.getDuration() == 0)
            .forEach(task -> task.setStatus(TaskStatus.SUCCESS));

          Thread.sleep(1000);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    };
    
    new Thread(taskPoolConsumer).start();
  }
  
  public void startAllTasks() throws InterruptedException {
    this.pool.stream().forEach(task -> task.start());  
  }

  public List getPool() {
    return this.pool;
  }

  public void addTask(Task taskToAdd) {
    this.pool.add(taskToAdd);
  }

}

3.4 The Web Service

To create the web service, we will be using the @RestController annotation from Spring. This web service will be mapped to "/api/task" and will answer POST and GET requests.

TaskService.java

@RestController
@RequestMapping("/api/task")
public class TaskService {
  @Autowired
  private TaskExecutor taskExecutor;
  
  @RequestMapping(method = RequestMethod.GET)
  public List getTasks() {
    return this.taskExecutor.getPool();
  }
  
  @RequestMapping(method = RequestMethod.POST)
  public void addTask(@RequestBody Task taskToAdd) {
    this.taskExecutor.addTask(taskToAdd);
  }
  
  public void startIdleTasks() throws InterruptedException {
    this.taskExecutor.startAllTasks();
  }
  
}

3.5 The ManagedBean to start the tasks

Finally, we have a managed bean of JSF to execute the code behind the last button.

TaskController.java

@ManagedBean(name = "taskController", eager=true)
@Component
@RequestScoped
public class TaskController {
  @Autowired
  private TaskService taskService;
  
  public void startTasks(ActionEvent event) throws InterruptedException {
    this.taskService.startIdleTasks();
  }
  
}

4. Front-end implementation with AngularJS

First, you want to create your module, then your controller. In the end result screenshot above, our controller will manage the first three buttons (Add Task, Refresh Tasks and Activate Auto Refresh). The last button is a JSF button managed by a backing bean.

index.xhtml

var part1 = angular.module("part1", []);
part1.controller("RealtimeCtrl", function($scope, $http, $timeout) {
  $scope.tasks = [];
  
  $scope.addTask = function() {
    $http.post("api/task", $scope.task);
  }
  
  $scope.getTasks = function() {
    $http.get("api/task")
      .success(function(data) {
        $scope.tasks = data;
      });
  }
  
  $scope.activateRealtime = function() {
    $scope.getTasks();
    $timeout($scope.activateRealtime, 1000);
  }
  
});

I used Angular’s dependency injection to get the $scope, $http and $timeout services. In the Angular scope, I initially set the list of tasks to an empty array which will be replaced by the tasks array returned by the web service. Now, we have our three functions. The first one is addTask() which simply creates an Ajax POST request to the server with the task object from Angular’s scope in the request data. The second function above is getTasks() which creates an Ajax GET request to the server. The server will return an array of JSON objects corresponding to the tasks registered on the server. The last but not the least function is the implementation of the real-time feel, that is a recursive function with a pause of a second that simply retrieves the tasks using the controller’s function getTask(). This is the complete index.xhtml code:

index.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:h="http://java.sun.com/jsf/html"  
    xmlns:f="http://java.sun.com/jsf/core">
    
  <h:head>
    <title>Real-time applications - Part 1 - Java Code Geeks</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script>
    
    <script>
      var part1 = angular.module("part1", []);
      part1.controller("RealtimeCtrl", function($scope, $http, $timeout) {
        $scope.tasks = [];
        
        $scope.addTask = function() {
          $http.post("api/task", $scope.task);
        }
        
        $scope.getTasks = function() {
          $http.get("api/task")
            .success(function(data) {
              $scope.tasks = data;
            });
        }
        
        $scope.activateRealtime = function() {
          $scope.getTasks();
          $timeout($scope.activateRealtime, 1000);
        }
        
      });
      
    </script>
  </h:head>
    
  <h:body>
    <div ng-app="part1" ng-controller="RealtimeCtrl" class="container">
      <h1>Real-time application <SMALL>part 1</SMALL></h1>
      <h2>Add task</h2>
      <h:form>
        <label for="durationField">Duration (in seconds):</label>
        <input type="number" id="durationField" class="form-control" ng-model="task.duration"/>
        <button type="button" ng-click="addTask()" class="btn btn-success">Add task</button>
        <button type="button" ng-click="getTasks()" class="btn btn-default">Refresh Tasks</button>
        <button type="button" ng-click="activateRealtime()" class="btn btn-default">Activate Auto Refresh</button>
        <h:commandButton actionListener="#{taskController.startTasks}" 
            styleClass="btn btn-default"
            value="Start Idle Tasks">
          <f:ajax execute="@form"/>
        </h:commandButton>
      </h:form>
      
      <h2>Listing</h2>
      <ul class="list-group">
        <li ng-repeat="curTask in tasks" class="list-group-item {{curTask.running ? 'active' : ''}}">
          {{curTask.name}} ({{curTask.status}})<span class="badge">{{curTask.duration}}</span>
        </li>
      </ul>
    </div>
  </h:body>    
</html>

5. What’s next?

Obviously, there are tons of different ways of implementing a real-time application with the Periodic Refresh pattern. I picked AngularJS along RESTful JSON Web service because AngularJS really simplifies the update of the UI without having to refresh the page.

In the next article, I will reuse the same application but I will show you how have a better feel of the real-time application. The part 2 will be on Long Polling and the part 3 on the spanking new HTML 5 WebSocket.

6. Download the Eclipse project

This was an example of how to integrate AngularJS and Spring MVC to create an application that is updated automatically using the Periodic Refresh design pattern.

Download
You can download the full source code of this example here: Real-time part 1

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area

 

Leave a Reply

Be the First to Comment!

avatar
  Subscribe  
Notify of