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. 

RestController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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:

bookController.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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.

service.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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:

home.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<%@ 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 

spring-angularjs-flow

Download Source Code:

spring-angular

About The Author

1 thought on “Spring MVC CRUD Operations using Angularjs”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.