Core Java

Java as RESTful backend of Angular.js

1. Introduction

In my last series of posts about real-time applications, I set up a little Java web application with Spring and Angular.js. I did not go in details about the architectural choices and the way I made Angular and Spring talk to each other. I thought a quick tutorial could be interesting.

2. Maven dependencies

The first thing we need is to setup Spring. For that, you need to add the Spring WebMVC dependency to your pom.xml. Under the hood, Maven will fetch the Spring MVC’s dependencies like Spring Core and Spring Context.

pom.xml

  <dependencies>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-webmvc</artifactId>
  		<version>4.2.1.RELEASE</version>
  	</dependency>
  	<dependency>
	  <groupId>com.fasterxml.jackson.core</groupId>
	  <artifactId>jackson-databind</artifactId>
	  <version>2.6.2</version>
    </dependency>
  </dependencies>

angularjs_small

AngularJS Programming Cookbook

In this ebook, we provide a compilation of AngularJS based examples that will help you kick-start your own web projects. We cover a wide range of topics, from Single Page Apps and Routing, to Data Binding and JSON Fetching. With our straightforward tutorials, you will be able to get your own projects up and running in minimum time. Download the cookbook by joining the Web Code Geeks Newsletter.

3. Setup Spring

3.1. Configuration with annotations

In order to have Spring configured, we need 2 things. The first one is the application initializer which has to be a subclass of AbstractAnnotationConfigDispatcherServletInitializer. Quick side note here regarding the name of that class. It’s long… Personally, I prefer seeing a name that long that having something like AbstractAnnConfDispServletInit like I did myself here with my AppInitializer and my AppConfig (!), or worse, AACDServletInit. That aside, this implementation will force you to override 3 functions. The main one that is interesting is getRootConfigClasses() which tells Spring which class is the configuration class. Those two classes replaces the configuration XML.

AppInitializer.java

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { AppConfig.class };
    }
  
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }
  
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
 
}

Here, I refer to a class named AppConfig. This class will have the @Configuration annotation and will define the component package for Spring to look in. The getServletMappings() function binds the URI path "/" to Spring’s request dispatcher, so in order to have static resources returned when queried, such as images, CSS and JS files, we also have to define a resource handler. This is done in the AppConfig file.

AppInitializer.java

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.javacodegeeks.examples.restfulbackend")
public class AppConfig extends WebMvcConfigurerAdapter {
	public static final String REST_API_ROOT = "/api/";
	
	@Override
	public void addResourceHandlers(final ResourceHandlerRegistry reg) {
		reg.addResourceHandler("/**").addResourceLocations("/");
	}

}

You can see here that Spring will search for components in com.javacodegeeks.examples.restfulbackend.

3.2. The Web Service

If you go back to the pom.xml above, you will see that there is Jackson DataBind in the dependencies. This will automatically convert all objects returned from the web service to the browser into Json ready to be processed by Angular. To create that web service, we will simply create a class with the @RestController annotation and implement the different mapping.

SpringContactCRUDRestController.java

@RestController
public class SpringContactCRUDRestController implements ContactCRUDController {
	@Autowired
	private ContactService contactService;
	
	@Override
	@RequestMapping(path = "/api/contact", method = RequestMethod.PUT)
	public void create(@RequestBody Contact contactToCreate) {
		this.contactService.create(contactToCreate);
	}

	@Override
	@RequestMapping(path = "/api/contact", method = RequestMethod.GET)
	public @ResponseBody List<Contact> get() {
		return this.contactService.get();
	}

	@Override
	@RequestMapping(path = "/api/contact/{id}", method = RequestMethod.GET)
	public @ResponseBody Contact getById(@PathVariable("id") Integer id) {
		return this.contactService.getById(id);
	}

}

All the business tier and the data storage is the same as in my previous article. It’s simply a repository I like to have to make proofs of concept. It allows to have a pseudo data store which is simply a Map holding a key and the object. Another thing I like to use in POC for data storage is the embedded database of Java called Apache Derby. This way you can use a JPA implementation and change to a real database later on. If you are interested in the repository I just described, please see my article on real-time applications.

4. The Angular Module and Controllers

As we have pretty much no business logic, all the layers I put in place might seem overkill, but I really think that even a POC or an example like this one should have a proper basic architecture with separations like this. Of course, in Angular, you should be using services for any business logic and reusable code.

contactApp.js

contactApp = angular.module("ContactApp", []);

contactApp.controller("ContactController", function($scope, $http) {
	$scope.contact = {};
	
	$scope.getAll = function() {
		$http.get('api/contact')
			.success(function(data) {				
				$scope.contacts = data;
			});
	};
	
	$scope.create = function() {
		$http.put('api/contact', $scope.contact)
			.success(function() {
				$scope.contact = {};
				$scope.getAll();
			});
	};
	
	$scope.get = function(id) {
		$http.get('api/contact/' + id)
			.success(function(data) {	
				$scope.contact = data;
			});
	};
	
	$scope.getAll();
});

Here, we use Angular’s $http service to create an XMLHttpRequest to our CRUD controller which accepts PUT and GET. The PUT method is used to create a new instance of the contact, and the GET method is used in two different ways. Either we query the controller for a specific contact by adding the id as a request parameter, or we retrieve all contacts using no parameters.

5. Conclusion

So, in this article, we learnt how we can make Angular speak directly to a Spring service using the $http service of the front-end framework. Using Jackson Databind along with Spring, we are able to have a web service that automatically converts our POJO to JSON and vice-versa. I think it’s important to notice also the way I implemented Spring’s configuration. I have absolutely no XML configuration files as it is done through Spring Java based configuration. This example could be interpreted as a simple startup project. I have done many tests to keep this as small as possible.

If you have any question, feel free to tweet at me (@syl20TOS) or send me a message on LinkedIn.

6. Download the Eclipse project

Download
You can download the full source code of this example here: Java as a Restful Back-end for AngularJS

Sylvain Cloutier

Sylvain has been programming in Java for the past 5 years, mainly in the aerospace industry, as a lead developer of complex web based aircraft wiring systems. He is also one of the organizers of the Java User Group of Quebec City and currently works as a Java developer consultant at CGI.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button