There are plenty of JavaScript frameworks available to send an Ajax request to the server; we decided to use AngularJS (https://angularjs.org/) as our frontend JavaScript library to send Ajax requests. AngularJS is more or less like a frontend MVC framework, but also has the concepts of Model, View, Controller and more. The only difference is that it is designed to work in the frontend using JavaScript.
In step 1, we just created our AngularJS-based Controller called controllers.js
in /src/main/webapp/resources/js/
. Remember, we purposely put this file under the resources
directory because from the client side we want to access this file as a static resource; we don't want to go through Spring MVC Controllers in order to get this file.
Okay, coming to the point, what have we written in controllers.js
? We have written five frontend Controller methods, namely refreshCart
, clearCart
, initCartId
, addToCart,
and removeFromCart
. These methods are used to communicate with the server using Ajax calls. For example, consider the following Controller method:
$scope.refreshCart = function(cartId) { $http.get('/webstore/rest/cart/' + $scope.cartId) .success(function(data) { $scope.cart = data; }); };
Within the refreshCart
method, using the AngularJS $http
object, we have sent an HTTP GET request to the URI template /webstore/rest/cart/'+$scope.cartId
. Based on the value stored in the $scope.cartId
variable, the actual request will be sent to the REST target URL. For instance, if the $scope.cartId
contains a value of 111
, then a GET request will be sent to the http://localhost:8080/webstore/rest/cart/
111
to get a cart
object whose ID is 111
as JSON data. Once we get the cart object as JSON data, we store it in the frontend Angular model using the $scope
object, as follows:
.success(function(data) { $scope.cart = data; }
Similarly, all other AngularJS Controller methods fire some Ajax web requests to the server, and retrieve or update the cart
. For example, the addToCart
and removeFromCart
methods are just adding a cartItem
and removing a cartItem
from the cart
object.
Okay, we have just defined our AngularJS Controller methods, but we have to invoke this method in order to do something useful, which is what we have done in step 2. In step 2, we just defined our regular Spring MVC Controller named CartController,
which has two request-mapping methods, namely get
and getCart
. Whenever a normal web request comes to the URL http://localhost:8080/webstore/cart,
the get
method will be invoked, and inside the get
method we have retrieved the session ID and used it as a cart ID to invoke the getCart
method. Here we maintained the session ID as the cart ID:
@RequestMapping public String get(HttpServletRequest request) { return "redirect:/cart/"+request.getSession(true).getId(); }
And within the getCart
method, we simply stored the cartId
in the Spring MVC Model and returned a View name as cart
. We did this kind of setup because we want our application to redirect the request to the correct cart based on the session ID whenever a request comes to the URL http://localhost:8080/webstore/cart
. Okay, since we have returned a View name as cart
, our dispatcher servlet would definitely look for a View file called cart.jsp
. That is why we have created the cart.jsp
in step 3.
cart.jsp
just acts as a template for our shopping cart page. The cart.jsp
page internally uses the AngularJS Controller's methods that we have created in step 1 to communicate with the server. The ng-repeat
directive of AngularJS would repeat the HTML table rows dynamically based on the cartItems
available in the cart
:
<tr ng-repeat="item in cart.cartItems">
<td>{{item.product.productId}}-{{item.product.name}}</td>
<td>{{item.product.unitPrice}}</td>
<td>{{item.quantity}}</td>
<td>{{item.totalPrice}}</td>
<td><a href="#" class="label label-danger" ng-click="removeFromCart(item.product.productId)">
<span class="glyphicon glyphicon-remove" /></span> Remove
</a>
</td>
</tr>
And the ng-click
directive from the remove <a>
tag would call the removeFromCart
Controller method. Similarly, to add a cartItem
to the cart, in product.jsp
we have added another ng-click
directive as follows in step 6 to invoke the addToCart
method:
<a href="#" class="btn btn-warning btn-large" ng-click="addToCart('${product.productId}')"> <span class="glyphicon-shopping-cart glyphicon"></span> Order Now </a>
So that's it, we have done everything to roll out our shopping cart in our application. After running our application, we can access our shopping cart under the URL http://localhost:8080/webstore/cart
and can even add products to the cart from each product detail page as well.