Java @ Desk: Angular JS | Java at your desk

Angular JS routing with Spring 4 MVC using ngRoute

Angular JS routing with Spring 4 MVC using ngRoute

This example demonstrates how routing works in angular js using ngRoute, $routeProvider.

Following components are used:
1) Spring 4.3.0.RELEASE
2) Angular JS 1.4.4
3) Angular JS Route 1.4.4

Configuring Routes
Routes in angular js are configured in the config function using the $routeProvider service. In the example, we will configure 2 routes, 1st to load the list of Persons and 2nd to load list of Customers.
1) templateUrl - This triggers the Spring's controller to decide which html page to navigate to
2) controller - This triggers the angular js controller
3) resolve - This triggers the angular js service

app.js
'use strict';

var indexApp = angular.module('indexApp', [ 'ngRoute' ]);

indexApp.config([ '$routeProvider', function($routeProvider) {
 $routeProvider.when('/loadPersons', {
  templateUrl : 'loadPersons',
  controller : "PersonController as personCtrl",
  resolve : {
   async : [ 'PersonService', function(PersonService) {
    return PersonService.fetchPersons();
   } ]
  }
 }).when('/loadCustomers', {
  templateUrl : 'loadCustomers',
  controller : "CustomerController as custCtrl",
  resolve : {
   async : [ 'CustomerService', function(CustomerService) {
    return CustomerService.fetchCustomers();
   } ]
  }
 });
} ]);


Service JS
Angular JS service file will communicate with the Spring controller where the services are configured. The call to spring is done using the $http.

appService.js
'use strict';

indexApp.factory('CustomerService', [ '$http', '$q', function($http, $q) {
 return {
  fetchCustomers : function() {
   return $http.get('customers').then(function(response) {
    return response.data;
   }, function(errResponse) {
    console.error('Error while fetching Items');
    return $q.reject(errResponse);
   });
  }
 };
} ]);

indexApp.factory('PersonService', [ '$http', '$q', function($http, $q) {
 return {
  fetchPersons : function() {
   return $http.get('persons').then(function(response) {
    return response.data;
   }, function(errResponse) {
    console.error('Error while fetching Items');
    return $q.reject(errResponse);
   });
  }
 };
} ]);


Controller Js
Angular JS controller file sets the response of service to the UI scope variables defined in JSP page.

appController.js
'use strict';

indexApp.controller('CustomerController', [ 'async', function(async) {
 var self = this;
 self.customers = async;
} ]);

indexApp.controller('PersonController', [ 'async', function(async) {
 var self = this;
 self.persons = async;
} ]);


Welcome Page
This page configures the indexApp ng app and displays the content using the ng-view directive.



index.jsp - In below JSP, when user clicks on "Get Persons List" hyperlink, it calls the config of app.js and check with the $routeProvider for the matching URL. It finds the "/loadPersons" and it hits the "templateUrl : 'loadPersons'" that goes to MainController.java to define the HTML page to navigate to. In MainController.java, it finds "persons" and so navigates to persons.jsp as shown below and displays the content on ng-view.

<!DOCTYPE html>
<html ng-app="indexApp">
<head>
<title>Person App</title>
<script src="resources/js/angular.js"></script>
<script src="resources/js/angular-route.js"></script>
<script src="resources/js/app.js"></script>
<script src="resources/js/appService.js"></script>
<script src="resources/js/jquery.min.js"></script>
</head>

<body>
 Home Screen
 <li><a href="#/loadPersons">Get Persons List</a></li>
 <li><a href="#/loadCustomers">Get Customers List</a></li>
 <div ng-view></div>
 <script src="resources/js/appController.js"></script>
</body>
</html>


persons.jsp
<!DOCTYPE html>
<html ng-app="personApp">
<head>
<title>Person App</title>
<script src="resources/js/angular.js"></script>
<script src="resources/js/angular-route.js"></script>
<script src="resources/js/app.js"></script>
<script src="resources/js/personService.js"></script>
<script src="resources/js/jquery.min.js"></script>
</head>

<body>
 Persons Data -
 <div ng-repeat="person in personCtrl.persons">
  Person Name - {{person.name}} <br> Person Id - {{person.id}}
 </div>
 <li><a href="#/back">Back</a></li>
 <script src="resources/js/personController.js"></script>
</body>
</html>


customers.jsp
<!DOCTYPE html>
<html ng-app="customerApp">
<head>
<title>Person App</title>
<script src="resources/js/angular.js"></script>
<script src="resources/js/angular-route.js"></script>
<script src="resources/js/appRoute.js"></script>
<script src="resources/js/customerService.js"></script>
<script src="resources/js/jquery.min.js"></script>
</head>

<body>
 Customers Data -
 <div ng-repeat="customer in custCtrl.customers">
  Customer Name - {{customer.name}} <br> Customer Id -
  {{customer.id}}
 </div>
 <li><a href="#/back">Back</a></li>
 <script src="resources/js/customerController.js"></script>
</body>
</html>

angular js $http rest controller status code 0

angular js $http rest controller status code 0

Angular JS $hhtp returns the status code 0 on calling the get request from the spring rest controller. The rest controller in the example below produces "application/json".

The response come fine if the URL is tested in the browser. It successfully prints the response on the chrome browser, but the same request returns the status code 0 if called from angular js $http. Below is the sample request and spring rest controller for the same.

angularController.js
var app = angular.module('customerApp', []);
app.controller("customerController", function($scope, $http) {
 $http.get('http://localhost:8060/customers').then(
   function successCallback(response) {
          $scope.customer = {name: response.data.name, id: response.data.id};
   }, function errorCallback(response) {
   });
});


CustomerController.java
package com.accenture.restviability.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.acc.auto.service.request.Customer;

@RestController()
public class CustomerController {

 @RequestMapping(method = RequestMethod.GET, path = "/customers", produces = MediaType.APPLICATION_JSON_VALUE)
 public ResponseEntity<Customer> getCustomers() {
  System.out.println("Entered in Get Customers");
  List<Customer> customers = new ArrayList<Customer>();
  Customer customer = new Customer();
  customer.setName("Kumar");
  customer.setId("1");
  return new ResponseEntity<Customer>(customer, HttpStatus.OK);
 }
}


The above angular method returns the status code 0 on calling the spring rest controller. The issue occure because of HTTP Access Control CORS issues.

Angular does not consume the response from the server that does not include Access-Control-Allow-Origin header in the response. The server responding back the angular JS calls must include the headers specified by CORS. In order to make it work, you need to include the below annotation of Spring.

@CrossOrigin(maxAge = 3600) from import org.springframework.web.bind.annotation.CrossOrigin;
package of Spring

Angular JS Spring MVC Rest CRUD JSON Example using $http

Angular JS Spring MVC Rest CRUD JSON Example using $http

In this example, we will learn how to get the json data from rest service controller from Spring and display using the ng-model attribute of angular JS.

Spring RestController returns the Customer java object in JSON format and data is displayed on UI using angular JS. Call to the rest api is done using the $http of angular JS.

Following components will be used
1) Spring RestController
2) Angular JS ng-app
3) Angular JS ng-controller
4) Angular JS ng-model
5) Angular JS $http

Here are the files that are used.

Customer.java
package com.accenture.restviability.pojo;

public class Customer {

 private String name;
 
 private String id;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }
}


SpringRestController
package com.accenture.restviability.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.accenture.restviability.pojo.Customer;
import com.google.gson.Gson;

@RestController()
@CrossOrigin(maxAge = 3600)
public class SpringRestController {

 @RequestMapping(method = RequestMethod.GET, path = "/customers", produces = MediaType.APPLICATION_JSON_VALUE)
 public ResponseEntity<Customer> getCustomers() {
  System.out.println("Entered in Get Customers");
  List<Customer> customers = new ArrayList<Customer>();
  Customer customer = new Customer();
  customer.setName("Kumar");
  customer.setId("1");
  Gson gson = new Gson();
  return new ResponseEntity<Customer>(customer, HttpStatus.OK);
 }
}




customer.jsp
<!DOCTYPE html>
<html ng-app="customerApp">
<head>
<title>Customer App</title>
<script src="js/angular.js"></script>
<script src="js/customerController.js"></script>
<script src="js/jquery.min.js"></script>
</head>

<body>
 <div ng-controller="customerController">
  <p>
   Customer Id - <input type="text" ng-model="customer.id" />
  </p>
  <p>
   Customer Name - <input type="text" ng-model="customer.name" />
  </p>
 </div>
</body>
</html>


customerController.js
var app = angular.module('customerApp', []);
app.controller("customerController", function($scope, $http) {
 $http.get('http://localhost:8070/customers').then(
   function successCallback(response) {
          $scope.customer = {name: response.data.name, id: response.data.id};
   }, function errorCallback(response) {
   });
});