Site icon Pro Liferay

Spring MVC CRUD Operations using Angularjs

spring-mvc-agular


Angularjs can be easily used with Spring MVC. In this article we will explain how Spring MVC and Angularjs can be used together. All the CRUD operations of spring controller will be exposed as rest web service. From Angularjs controller we can easily invoke rest services to create, read, update and delete the data.


Preparing Spring Rest Controller:

All the operations for database are written in rest controller. 

package com.proliferay.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.proliferay.model.Book;
import com.proliferay.service.BookService;

/**
 * 
 * @author Hamidul Islam
 *
 */

@Controller
public class RestController {  
	@Autowired
	private BookService bookService;      
	@RequestMapping(value = "/rest/getAllBook", method = RequestMethod.GET)
	public @ResponseBody List getAllBook() {
		System.out.println("#########getAllBook()#########");
		List<Book> bookList = bookService.findAllBooks();
		return bookList;
	}
	
	@RequestMapping(value = "/rest/addBook", method = RequestMethod.POST)
	public @ResponseBody String addBook(@RequestBody Book book) { 
		System.out.println("#########addBook()#########");
		bookService.addBook(book);
		return "OK";
	}
	
	@RequestMapping(value = "/rest/updateBook", method = RequestMethod.POST)
	public @ResponseBody String  updateBook(@RequestBody Book book) {
		System.out.println("#########updateBook()#########");
		bookService.updateBook(book); 
		return "OK";
	}
	
	@RequestMapping(value = "/rest/deleteBook", method = RequestMethod.POST)
	public @ResponseBody String  deleteBook(@RequestBody Book book) {
		System.out.println("#########deleteBook()#########");
		bookService.deleteBook(book.getId());
		return "OK";
	}
}

@ResponseBody:

Give attention to @ResponseBody annotation. If a method is annotated with @ResponseBody the controller will automatically converts the returned contents and writes to the http response. In the getAllBook method the returned list will be automatically converted to JSON and will be written to http response.

Preparing Angularjs Controller:

function bookController($scope, BookService) {
	var self = this;
	$scope.book = {};
	self.books = [];
	$scope.action = 'add';
	$scope.message = '';

	

	getAllBooks();

	function getAllBooks() {
		console.log("####bookController:getAllBooks()#########");
		BookService.getAllBook().then(function(d) {
			self.books = d;
		}, function(errResponse) {
			console.error(errResponse);
		});

	}

	$scope.add = function() {
		console.log("####bookController:add()#########");
		var json = angular.toJson($scope.book)
		BookService.addBook($scope.book).then(function(d) {
			$scope.message = 'Book Added Successfully';
			getAllBooks();
			$scope.clear();
		}, function(errResponse) {
			console.error(errResponse);
		});
	}

	$scope.update = function() {
		console.log("####bookController:update()#########");
		BookService.updateBook($scope.book).then(function(d) {
			$scope.message = 'Book Updated Successfully';
			getAllBooks();
		}, function(errResponse) {
			console.error(errResponse);
		});
	}
	
	$scope.clear = function() {
		console.log("####bookController:clear()#########");
		$scope.book = {};
		$scope.action = 'add';
		
	}
	
	$scope.edit = function(book) {
		console.log("####bookController:edit()#########");
		$scope.book = book;
		$scope.action = 'update';
	}

	$scope.deleteBook = function(book){
		console.log("####bookController:deleteBook()#########");
		BookService.deleteBook(book).then(function(d) {
			$scope.message = 'Book Delted Successfully';
			getAllBooks();
		}, function(errResponse) {
			console.error(errResponse);
		});
	}
}

var app = angular.module('bookApp', [ 'MyOwnService' ]);
app.controller('bookController', bookController);

Writing the front end service:

All the front end  operations are kept inside a factory. The factory method can be easily called from front end controller.

var validationHandler = angular.module('MyOwnService', []);
validationHandler.factory('BookService', function($http, $q) {
	var REST_SERVICE_URI = 'http://localhost:8080/angular/';
	var factory = {
		getAllBook : getAllBook,
		addBook : addBook,
		updateBook : updateBook,
		deleteBook : deleteBook
	};
	return factory;

	function getAllBook() {
		console.log("####service:getAllBook()#########");
		var deferred = $q.defer();

		$http.get(REST_SERVICE_URI + 'rest/getAllBook').then(
				function(response) {

					deferred.resolve(response.data);
				}, function(errResponse) {
					console.error(errResponse);
					deferred.reject(errResponse);
				});

		return deferred.promise;
	}

	function addBook(book) {
		console.log("####service:addBook()#########");
		var deferred = $q.defer();

		$http.post(REST_SERVICE_URI + 'rest/addBook', book).then(
				function(response) {
					deferred.resolve(response.data);
				}, function(errResponse) {
					console.error(errResponse);
					deferred.reject(errResponse);
				});

		return deferred.promise;
	}

	function updateBook(book) {
		console.log("####service:updateBook()#########");
		var deferred = $q.defer();

		$http.post(REST_SERVICE_URI + 'rest/updateBook', book).then(
				function(response) {

					deferred.resolve(response.data);
				}, function(errResponse) {
					console.error(errResponse);
					deferred.reject(errResponse);
				});

		return deferred.promise;
	}

	function deleteBook(book) {
		console.log("####service:deleteBook()#########");
		var deferred = $q.defer();
		$http.post(REST_SERVICE_URI + 'rest/deleteBook', book).then(
				function(response) {

					deferred.resolve(response.data);
				}, function(errResponse) {
					console.error(errResponse);
					deferred.reject(errResponse);
				});

		return deferred.promise;
	}
});

The view page:

<%@ include file="/WEB-INF/views/init.jsp"%>
<!DOCTYPE html>
<html>
<body ng-app="bookApp">

	
<div ng-controller="bookController as ctrl">

<h3>{{message}}</h3>


<table class="table">
			
<tr>
				
<td>Book Title:</td>


<td><input type="text" name="bookTitle" ng-model="book.bookTitle" /></td>

			</tr>


<tr>
				
<td>Author Name:</td>


<td><input type="text" name="authorName" ng-model="book.authorName" /></td>

			</tr>


<tr>
				
<td>Book Description:</td>


<td><input type="text" name="bookDescription" ng-model="book.bookDescription" /></td>

			</tr>


<tr>
				
<td>Book Price:</td>


<td><input type="text" name="bookPrice" ng-model="book.bookPrice" /></td>

			</tr>


<tr>
				
<td>ISBN:</td>


<td><input type="text" name="isbn" ng-model="book.isbn" /></td>

			</tr>


<tr>
				
<td ng-if="action == 'add' "><input type="button" value="Submit" ng-click="add()" /></td>


<td ng-if="action == 'update' "><input type="button" value="Update" ng-click="update()" /></td>


<td><input type="button" value="Clear" ng-click="clear()" /></td>

			</tr>

		</table>


<div>

<h2>List of Books</h2>


<table border="1">
				
<thead>

<tr>
						
<th>Serial No</th>


<th>Title</th>


<th>Author Name</th>


<th>Description</th>


<th>Price</th>


<th>ISBN</th>


<th>Action</th>

					</tr>

				</thead>


<tbody>
					
<tr ng-repeat="book in ctrl.books">
						
<td>{{$index + 1}}</td>


<td><span ng-bind="book.bookTitle"></span></td>


<td><span ng-bind="book.authorName"></span></td>


<td><span ng-bind="book.bookDescription"></span></td>


<td><span ng-bind="book.bookPrice"></span></td>


<td><span ng-bind="book.isbn"></span></td>


<td>
							<button type="button" ng-click="edit(book)">Edit</button>
							<button type="button" ng-click="deleteBook(book)">Delete</button>
						</td>

					</tr>

				</tbody>

			</table>

		</div>

	</div>


</body>
</html>

The flow will look like below 

Download Source Code:

spring-angular

Exit mobile version