spring mvc + angularjs integration example + annotation/JavaConfig

By Dhiraj Ray, 13 November,2016  

This post is about integrating spring mvc with angularjs. Here we will be using annotation based spring configuration with Beans defined in Java to integrate AngularJs. We will be creating a single page application using angularJs and spring to show the user details in a bootstrap table after a successful login. If you want to check or revise your AngularJS facts and concepts then you can check out AngularJS Interview Questions or AngularJS Objective Questions.

Environment Setup

1. JDK 8 2. Spring 4 3. Intellij Idea/ eclipse 4. Angular Js and bootstrap library 5. Maven 6. Apache tomcat

Maven Dependencies

No extra maven dependencies apart from spring mvc maven dependencies are required to develop this application. But you can still use webjars maven dependecies instead of manually including js libraries.

pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.developerstack</groupId> <artifactId>jms-spring-integration</artifactId> <version>0.1.0</version> <properties> <spring.version>4.1.0.RELEASE</spring.version> <jackson.version>2.7.2</jackson.version> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.6.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml$gt </configuration> </plugin> </plugins> </build> </project>

Spring Bean Configuration

This configuration is responsible to initialize spring based web application. We have implemented WebApplicationInitializer.java to configure the ServletContext programmatically.

ApplicationInitializer.java
package com.developerstack.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class ApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(BeanConfig.class); ctx.setServletContext(container); ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx)); servlet.setLoadOnStartup(1); servlet.addMapping("/"); } }

Now let us configure our beans. Here we do not require any explicit bean to define. ComponentScan will register our bean.

@Configuration : It indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime

@EnableWebMvc: Adding this annotation to an @Configuration class imports the Spring MVC configuration from WebMvcConfigurationSupport

BeanConfig.java
package com.developerstack.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @EnableWebMvc @ComponentScan(basePackages = "com.developerstack") public class BeanConfig { }

Now let us configure the provision for handling our static contents. This is also configured using java config. Our all static resources are under the folder ui. So we need to tell this to Spring that any static resources request should be looked inside ui folder.

WebConfig.java
package com.developerstack.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(final ResourceHandlerRegistry registry) { registry.addResourceHandler("/js/**").addResourceLocations("/ui/js/"); registry.addResourceHandler("/css/**").addResourceLocations("/ui/css/"); registry.addResourceHandler("/*.html/**").addResourceLocations("/ui/views/"); } }

Server Side

Now let us define our controller. This controller will map the requests coming from angular service. Here we have 2 mappings to validate the user credentials and to load the user details.

UserController.java
package com.developerstack.controller; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; 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 com.developerstack.model.UserDetails; import com.developerstack.service.UserService; import com.google.gson.Gson; @Controller public class UserController { @Autowired private UserService userService; @RequestMapping(value = "/validate", method = RequestMethod.POST) public ResponseEntity validate(@RequestBody String userString, HttpServletRequest request) { Map user = new Gson().fromJson(userString, Map.class); userService.validateUser(user, request); return new ResponseEntity(HttpStatus.OK); } @RequestMapping(value = "/details", method = RequestMethod.GET) public ResponseEntity> userDetails() { List userDetails = userService.getUserDetails(); return new ResponseEntity>(userDetails, HttpStatus.OK); } }

Following is the POJO. This will be used to send user details as a response to the client.

UserDetails.java
package com.developerstack.model; public class UserDetails { private String firstName; private String lastName; private String email; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }

Let us define our service. Following service implementation is very basic. You can add your dao implementation as per your requirement and inject here. Here user credentials is hard coded as admin/admin

UserServiceImpl.java
package com.developerstack.service.impl; import java.util.Arrays; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Service; import com.developerstack.model.UserDetails; import com.developerstack.service.UserService; @Service public class UserServiceImpl implements UserService { public void validateUser(Map user, HttpServletRequest request) { String userName = user.get("email"); String password = user.get("password"); if(!(userName.equals("admin") && password.equals("admin"))) { throw new RuntimeException("Invalid user"); } } public List getUserDetails() { UserDetails ud1 = new UserDetails(); ud1.setEmail("john@example.com"); ud1.setFirstName("John"); ud1.setLastName("Doe"); UserDetails ud2 = new UserDetails(); ud2.setEmail("vicky@gmail.com"); ud2.setFirstName("vicky"); ud2.setLastName("Ray"); UserDetails ud3 = new UserDetails(); ud3.setEmail("abc@yahoo.co.in"); ud3.setFirstName("abc"); ud3.setLastName("greg"); UserDetails ud4 = new UserDetails(); ud4.setFirstName("xyz"); ud4.setEmail("xyz@gmail.com"); ud4.setLastName("Bard"); return Arrays.asList(ud1, ud2, ud3, ud4); } }

Client Side

Client side we have defined 2 .js file - userController.js and userService.js and two html pages - one with login form and another with user details. Let us look into those one by one. This page contains the login form and once the user is verified it will show the detail of user. User detail is rendered in another .html page - userDetails.html

index.html
<!DOCTYPE html> <html lang="en"> <head> <title>login</title> <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/font-awesome.min.css"> <link rel="stylesheet" href="css/dashboard.css"> <script src="js/plugins/jquery-2.2.1.min.js"></script> <script src="js/plugins/angular-1.4.9.min.js"></script> <script src="js/plugins/bootstrap.min.js"></script> <body ng-app="app" ng-controller="userController"> <div class="container"> <div class="row" style="margin-top:50px;"> <div class="col-md-offset-2 col-md-4" style="border: 2px solid green;" ng-show="showLogin" > <h2 class="text-center">Login Form</h2> <form class="form-horizontal" ng-submit="login()"> <fieldset> <div class="control-group"> <label class="control-label" for="email">Email:</label> <div class="controls"> <input id="loginEmail" name="email" ng-model="user.email" class="form-control" type="text" placeholder="Enter your email" class="input-large"> </div> </div> <div class="control-group"> <label class="control-label" for="password">Password:</label> <div class="controls"> <input id="loginPassword" ng-model="user.password" name="password" class="form-control" type="password" placeholder="********" class="input-medium"> </div> </div> <div class="control-group"> <label class="control-label" for="signin"></label> <div class="controls"> <input type="submit" id="submit" class="btn btn-success" value="Sign In" /> </div> </div> </fieldset> </form> </div> </div> <div ng-show="showUserDetails" ng-include="'userDetails.html'"> </div> </div> <script>var App = angular.module('app',[]);</script> <script src="js/service/userService.js"></script> <script src="js/controller/userController.js"></script> </body> </html>

The controller here is the angular controller. userService is injected here which in turn wil communicate with the server and get the data.

userController.js
'use strict'; App.controller('userController', ['$scope', '$rootScope', 'userService', '$http', function($scope, $rootScope, userService, $http) { $scope.user = {}; $scope.user.email = ""; $scope.user.password = ""; $scope.showUserDetails = false; $scope.showLogin = true; $scope.userDetails = []; $scope.login = function() { userService.postUserData($scope.user).then( function(d) { $scope.showLogin = false; $scope.showUserDetails = true; $scope.getUserDetails(); }); }; $scope.getUserDetails = function() { userService.getUserDetails().then( function(d) { $scope.userDetails = d; }); } } ]);

Now let us define the service.

userService.js
'use strict'; App.factory('userService', function($http, $q) { return { postUserData : function(user){ var config = { headers : { 'Content-Type': 'application/json' } } return $http.post('validate', user, config) .then( function(response){ return response.data; }, function(errResponse) { alert(errResponse.status + ':' + errResponse.statusText); return $q.reject(errResponse); }); }, getUserDetails : function() { return $http.get('details') .then( function(response){ return response.data; }, function(errResponse) { alert(errResponse.status + ':' + errResponse.statusText); return $q.reject(errResponse); }); } }; });

Run Application

1. Deploy the app o tomcat 2. Hit the url - http://localhost:8080/spring-angular-integration/index.html. Following screen will appear. login-form 3. Now enter the userId and password as admin and admin. 4. Once validated following screen will appear.

dashboard

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download the source

References: Spring Framework References Angulr Docs Spring Boot References

Suggest more topics in suggestion section or write your own article and share with your colleagues.

Is this page helpful to you? Please give us your feedback below. We would love to hear your thoughts on these articles, it will help us improve further our learning process.

Further Reading: