Develop a web application with AngularJS and Spring MVC

Nowadays customers have a rich web experience with Gmail, Google Apps, Facebook and Twitter. A basic server side rendered web pages doesn’t fit anymore to the new HMI (human-machine interface) needs.

AngularJs is one of the most successful front-end frameworks for RIA (Rich Internet Application Development) development.

AngularJs encourages the use of the Model-View-Controller (MVC) design pattern to decouple the code and to separate concerns.

   

Denver Art Museum / Daniel Libeskind

Despite the Javascript language specificities, a JEE developer will appreciate having some best practice and design patterns that he’s familiar with.

This article illustrate how to integrate AngularJs to a Spring MVC project. I hope this article will help developers to take the plunge and start using AngularJs.

The sample project source code is available on this link github.com/samer-abdelkafi/ng-project.
The sample IHM Demo is available here.

1. Add AngularJs librery

I adopted Webjars as a way to manage static web resources via the Maven dependency management mechanism. This could be done by front package manager like Bower.

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>angularjs</artifactId>
    <version>1.3.8</version>
</dependency>


Add ResourceHandler for webjars to your Spring configuration file if it isn’t already done.

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = { "com.mycompany.myproject.web.controller" })
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
    // Non shown code
}

2. Develop the business logic

In this sample project, we have a simple business logic. The front-end get a list from a rest web service and display it.
The code bellow presents our business logic implementation.

Add a new javasvript file app.js.

angular
    .module('myApp', ['ngResource'])
    .service('UsersService', function ($log, $resource) {
        return {
            getAll: function () {
                var userResource = $resource('users', {}, {
                    query: {method: 'GET', params: {}, isArray: true}
                });
                return userResource.query();
            }
        }
    })
    .controller('UsersController', function ($scope, $log, UsersService) {
        $scope.users = UsersService.getAll();
    });

myApp : root module for the project.
UsersService : service for executing the http request
UsersController : controller executed when the page is loaded.

3. Develop the view part

AngularJs implements MVC pattern. The html page is the view part, the controller is developed client side by java script and the model is Json object to get from the server side.

Import AngularJs library to your Html code.

<!DOCTYPE html ng-app="myApp">
<html ng-controller="UsersController">
<!-- header code -->
<body>

<div ng-repeat="user in users">{{user.firstName}} {{user.familyName}}</div>

<script type="text/javascript" src="webjars/jquery/2.1.1/jquery.js"></script>
<script type="text/javascript" src="webjars/angularjs/1.3.8/angular.min.js"></script>
<script type="text/javascript" src="webjars/angularjs/1.3.8/angular-resource.min.js"></script>
</body>
</html>

4. Deploy and run the application

Now we will deploy and run the application to verify the configuration.

5. Application enhancement

5.1 Design enhancement

To enhance the application design, we use twitter bootstrap librery with a material design theme.

  • first step, add dependency for jquery, bootstrap and bootstrap-material-design using webjars.
  • Next, import css and js files to the html page.
  • finally, modify html code for displaying the list.

5.2 Functional enhancement

AngularJS comes with many handy filters built-in. We use “filter:string” to add search function. All strings or objects with string properties in array that match this string will be returned.

<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
    <meta charset="UTF-8">
    <link rel="stylesheet" href="webjars/bootstrap/3.2.0/css/bootstrap.css">
    <link rel="stylesheet" href="webjars/bootstrap-material-design/0.2.1/css/material.css">
    <title></title>
</head>
<body ng-controller="UsersController">

<div class="row">
    <br>
    <div class="container">
        <div id="userList" class="col-sm-offset-1 col-sm-10">
            <div class="input-group">
                <input class="form-control" id="search" name="search" placeholder="Search for" ng-model="query"
                       required="required"/>
              <span class="input-group-btn">
                  <button type="submit" class="btn btn-default">
                      <i class="glyphicon glyphicon-search"></i>
                  </button>
              </span>
            </div>
            <div class="list-group">
                <div class="list-group-item">
                    <div ng-repeat="user in users | filter:query" class="list-group-item" style="margin-top:16px">
                        <div class="row-picture">
                            <img class="circle"
                                 src="http://i.forbesimg.com/media/lists/people/{{user.firstName | lowercase}}-{{user.familyName | lowercase}}_50x50.jpg"
                                 alt="icon">
                        </div>
                        <div class="row-content">
                            <h4 class="list-group-item-heading">{{user.firstName}} {{user.familyName}}</h4>

                            <p class="list-group-item-text"><i class="glyphicon glyphicon-envelope"></i> {{user.email}}
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script type="text/javascript" src="webjars/jquery/2.1.1/jquery.js"></script>
<script type="text/javascript" src="webjars/angularjs/1.3.8/angular.min.js"></script>
<script type="text/javascript" src="webjars/angularjs/1.3.8/angular-resource.min.js"></script>
<script type="text/javascript" src="webjars/bootstrap-material-design/0.2.1/js/material.js"></script>
<script type="text/javascript" src="resources/js/app.js"></script>
</body>
</html>

The picture bellow presents a print screen for the application.

I think AngularJs, is one of the best front-end framework. It has many great features like data binding, dependency injection, MVC pattern implementation and page templates.

The major new version 2.0 of AngularJS has a significant deference from version 1.X, but it doesn’t seem to have migration path. AngularJs developers will encounter a drastically different looking framework and will need to learn a new architecture.

Even though there is no compatibility with the version 2.0, actual version has many good features and it’s still a good choice as a front-end framework.

Spring MVC – Full java based config

Spring MCV is a very powerful and flexible framework for web application development.

It doesn’t just implement the MVC pattern, it allows you to develop Rest web services.

   

This post presents a web project sample with a full java configuration using Spring MVC 4 and Servlet 3 api. The source code is available in this link.

This project implements client side for the persistence sample presented in Spring-Data-JPA article

1 – Add project dependencies

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.0.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

2 – Spring MVC config class

import org.springframework.context.annotation.*;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = { "com.mycompany.myproject.web.controller" })
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public InternalResourceViewResolver jspViewResolver() {
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        bean.setPrefix("/WEB-INF/views/");
        bean.setSuffix(".jsp");
        return bean;
    }

    @Bean(name = "multipartResolver")
    public CommonsMultipartResolver getMultipartResolver() {
        return new CommonsMultipartResolver();
    }

    @Bean(name = "messageSource")
    public ReloadableResourceBundleMessageSource getMessageSource() {
        ReloadableResourceBundleMessageSource resource = new ReloadableResourceBundleMessageSource();
        resource.setBasename("classpath:messages");
        resource.setDefaultEncoding("UTF-8");
        return resource;
    }

}


3 – Webapp initializer

With servlet 3 API you can use a class to configure your web project instead of the classic web.xml file.
You have to check if your application server or your servlet container supports servlet 3 spec. For Tomcat you can have this information in this link:
tomcat.apache.org/whichversion

import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ServiceConfig.class, JPAConfig.class, SecurityConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
        dispatcherServlet.register(MvcConfig.class);
            
        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
        
    }

 }


4 – Model class.

public class User {
 
    private Long id;

    private String firstName;

    private String familyName;

    private String email;

    // add extra attributes
    	
    // add getters and setters
	
}

5 – Add view as jsp page
We create a usersView.jsp page with code source bellow to display users list.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<div class="col-sm-offset-1 col-sm-10">

    <legend>
        <spring:message code="table.user.title" />
    </legend>

    <div>
        <table id="dataTable" class="table table-striped table-bordered">
            <thead>
                <tr>
                    <th><spring:message code="table.user.id" /></th>
                    <th><spring:message code="table.user.firstName" /></th>
                    <th><spring:message code="table.user.falilyName" /></th>
                    <th><spring:message code="table.user.email" /></th>
                </tr>
            <thead>
            <tbody>
                <c:forEach var="u" items="${usersModel}">
                    <tr>
                        <td>${u.id}</td>
                        <td>${u.firstName}</td>
                        <td>${u.familyName}</td>
                        <td>${u.email}</td>
                    <tr>
                </c:forEach>
            </tbody>
        </table>
    </div>
</div>

6 – Develop your controller

The @Controller annotation indicates that a particular class serves the role of a controller.
The @RequestMapping annotation is used to map a URL to either an entire class or a particular handler method.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class UserController {

    @Autowired
    private UserService userService;
 
    /**
    * Request mapping for user
    */
    @RequestMapping(value = "users", method = RequestMethod.GET)
    public ModelAndView getUsersView() {
        ModelAndView mv= new ModelAndView("usersView");
        mv.addObject("usersModel", userService.findAll());
        return mv;
    }
    
    /**
    * Rest web service
    */
    @RequestMapping(value = "/usersList", method = RequestMethod.GET)
    public @ResponseBody List<UserDto> getUsersRest() {
        return userService.findAll();
    }
}

7 – Test web project
When building your project you may have maven error telling you that the web.xml file is missing.
You can fix it by configuring the maven war plugin as presented bellow.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>

  • Test display users
    http://localhost:8080/myproject/users
    spring_mvc_test

  • Test rest web service
    http://localhost:8080/myproject/usersList
    You will get json reponse.

    [
        {
            "id": 1,
            "firstName": "adminName",
            "familyName": "adminFamily",
            "email": "admin@maycompany.com",
            "phone": "0033 1 23 45 67 89",
            "language": "en",
            "login": "admin",
            "password": "admin",
            "burthDate": null,
            "authorities": [
                {"id": 3, "name": "user"},
                {"id": 2, "name": "technical user"},
                {"id": 1, "name": "admin"}
            ],
            "enabled": true,
            "pictureId": null,
            "authoritiesAsString": "user, technical user, admin"
        },
        ..........
    ]
    

Here’s the how to video created by Webucator.com. Check out their Spring training classes.

Web design with 960 grid system

Sometimes we lose a lot of time solving some web design problems like unstable components positions or page structure. Often web pages change with screen width, content and web browser.

Some CSS frameworks like BluePrint and 960 Grid System cut down development time. They give a web developer a solid foundation to build UI with an easy-to-use grid and other features.

   

Photo credit: HannyB

This article presents 960 Grid System and suggests to integrate it in a dynamic web project (JEE JSF web project).

How 960 grid system works?

960 grid System framework propose two ways to manage the web page area. The first one use the central part of the web page with a fixe width. The second way use fluid width to define the exploited area of the page.

960 grid System framework uses the css class name to manage DIV position and the inner component position into the web page.

A row is defined by the container which is a div used to specify how many total columns exist, either 12 or 16.

If a grid unit contains grid children, the child need to a class which will indicate a number of columns it will take (grid_X). If you want to insert empty space before or after a grid unit, use class prefix_P or suffix_S.

container_12

pref grid_10 prefix_2 suffix_1 suf


The picture above explains how to use 960 grid CSS to manage Div positions. The content of the grid will be in the green area.

After we have a look to basic use case of the 960 grid framework, we will try to integrate it in a web application to manage screen components position.

960 grid in JEE project

Usually, the first step in UI design we define the page template. The picture bellow presents a template that we suggest to use for a project sample.

template
header
menu
content
footer
960px

960 grid system gives us the possibility to choose the way to place the different part of the application user interface into a grid system. We made a choice to use fixed width of 960px with 12 grids.

To use 960 grid system in your template page you need to add 960.css to the CSS folder of the web project and reference it.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
	xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href="#{request.contextPath}/css/default.css"  rel="stylesheet" type="text/css"/>
<link href="#{request.contextPath}/css/960.css"  rel="stylesheet" type="text/css"/>
<title>Sample Template</title>
</head>
<body >

<div id="wrap">
	<div id="header" class="container_12">
		<ui:include src="/pages/template/header.xhtml" />
	</div>
	<div id="main" class="container_12">
		<div id="menu" class="grid_2 " >
			<ui:include src="/pages/template/menu.xhtml" />
		</div>
		<div id="content" class="grid_6  prefix_2 suffix_2">
			<ui:insert name="body" />
		</div>
	</div>

</div>
<div id="footer" class="container_12" >
		<ui:include src="/pages/template/footer.xhtml" />
</div>

</body>
</html>

The picture bellow presents the application interface after we applied the 960 grid system.

My favorite Firefox Plugins

I have tried many web browsers since my first internet experience. Internet Explorer (IE) is the first one I had used, because it is the default browser installed in my operating system. At the university, I start believing on the Linux revolution and in this period I discovered the Netscape browser which has been a serious alternative to IE. Netscape had lost his success and the usage share of Netscape browsers had fallen, between 1998 and 2002 (ref: Wikipedia).

   

Photo credit: Kawartha Kurt

After Netscape fail, some good web browsers appear like Opera, Safari, FireFox. And those last years we assist to the Google Chrome browser beginning.

Until now my favorite web browser still Firefox. It has more than 60 000 plugins or Add-ons (ref: Add-on statistics). In this article I will present the most useful and amazing Firefox plugins I use today.


Utilities
Delicious Bookmarks : it access your delicious account and help you tag and manage your favorite WEB sites links.
Password Exporter : This extension allows you to export your saved passwords and disabled login hosts using XML or CSV files that can be imported in another browser or computer.

Pictures and videos
Cooliris: it is a picture and video browser. It gives you another way to explore pictures and videos.
Video DownloadHelper: it is a great Add-on which helps you download and save streaming videos from many web sites like (Youtube, Facebook …).

Development
Firebug: this add-on is dedicated to web developer or designer. It can help them debug JavaScript and solve some problems related to the style sheets CSS or HTML code.
Web Developper: the Web Developer extension adds a menu and a toolbar with various web developer tools.
Selenium IDE : It records web page navigation. It is a great tool to develop fonctional test.

Spread Firefox Affiliate Button