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.
You can follow this article for Angular 8 integration with Spring Boot.
I thought these articles - Spring Boot Angular Example, Angular 7 CRUD Example, Angular 6 Example also might be helpful to you for the latest versions of Angular.
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 MVC Configuration
This configuration is responsible to initialize spring based web application. We have implemented WebApplicationInitializer.java to configure the ServletContext programmatically.
ApplicationInitializer.javapackage 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("/"); } }
Other Interesting Posts Angular Js Spring Boot File Upload Spring Boot Angular Deployment Spring Boot Actuator Guide Spring Hibernate Integration with complete JavaConfig Spring Ehcache Cacheable Example with complete javaConfig Spring Boot Spring MVC Example Spring Security Hibernate Example with complete JavaConfig Securing REST API with Spring Security Basic Authentication Spring Security Password Encoding using Bcrypt Encoder Spring JMS Activemq Integration with Spring Boot Websocket spring Boot Integration with complete JavaConfig Maintaining Spring Session during Websocket Connection Spring Junit Integration with complete JavaConfig Spring Boot Thymeleaf Example
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.javapackage 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.javapackage 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/"); } }
Spring Controller and Service Implementation
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.javapackage 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) { Mapuser = 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.javapackage 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.javapackage 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(Mapuser, 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); } }
Angular JS Implementation
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. 3. Now enter the userId and password as admin and admin. 4. Once validated following screen will appear.
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.