Spring HATEOAS Rest API + JQuery Ajax POST/GET example | Spring Boot

Spring HATEOAS Rest API + JQuery Ajax POST_GET example _ Spring Boot

In this tutorial, JavaSampleApproach shows you a Spring Boot example that uses Spring HATEOAS Rest API with JQuery Ajax.

Related Posts:
How to start Spring HATEOAS RestAPI with Spring Boot
How to integrate JQuery Ajax POST/GET & Spring MVC | Spring Boot
How to start with JSP page and static resources in Spring Boot
Consume Spring HATEOAS Rest API using JQuery Ajax example | Spring Boot

I. Overview

1. Goal

We’ll build a Spring Boot Application in that:
HATEOAS REST Service provides interface for interacting with Customer Database.
– Client calls API by using JQuery Ajax POST/GET:
+ POST: submit new Order for specific Customer by CustomerId (assume that we have had Customer Database before: 3 customers, we just add new Order information).
+ GET: retrieve Customer Data (Id, Name, Orders List) by CustomerId

When displaying Customer Data for HTTP GET, our application can also show links to current Customer and its Orders.

2. Technology

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.4.RELEASE
– Spring Boot: 1.5.4.RELEASE

3. Project Structure

spring-hateoas-ajax-post-get-structure

HATEOAS REST Service:
+ Customer class extends Spring HATEOAS ResourceSupport.
+ CustomerRepository provides repository methods and custom finder methods for CustomerController to interact with Customer, Order database.
+ CustomerController is a REST Controller which has request mapping methods for RESTful requests such as:
/{id}, /{id}/orders, /postorder , /getcustomer/{id}
+ Request and Response class define data structures for returned data of HTTP POST/GET.

For more details about creating HATEOAS REST Service, please visit:
How to start Spring HATEOAS RestAPI with Spring Boot

JQuery Ajax POST/GET:
+ home.jsp contains form and elements for submitting POST/GET request.
+ ajax() POST/GET methods in get.js, post.js Javascript file.
+ WebController maps url to home.jsp page.

For more simple example about JQuery Ajax POST/GET, please visit:
How to integrate JQuery Ajax POST/GET & Spring MVC | Spring Boot

– Configuration for JSP page and static resources in application.properties
– Dependencies for Spring HATEOAS, WEB MVC, Tomcat in pom.xml

To know how to make application work with JSP page and static resources, please visit:
How to start with JSP page and static resource in Spring Boot

II. Practice

1. Create Spring Boot project

– Using Spring Tool Suite/Eclipse to create Project (WAR packaging), ServletInitializer and SpringBootApplication class will be created automatically.
– Add Dependencies to pom.xml file:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-tomcat</artifactId>
	<scope>provided</scope>
</dependency>

<dependency>
	<groupId>org.apache.tomcat.embed</groupId>
	<artifactId>tomcat-embed-jasper</artifactId>
	<scope>provided</scope>
</dependency>

2. Create Data Model Classes


package com.javasampleapproach.ajaxhateoas.model;

public class Order {

	private String name;

	public Order(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

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

}

package com.javasampleapproach.ajaxhateoas.model;

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

import org.springframework.hateoas.ResourceSupport;

public class Customer extends ResourceSupport {

	private Long customerId;
	private String name;

	private List orders;

	public Customer() {
	}

	public Customer(Long customerId, String name) {
		this.customerId = customerId;
		this.name = name;
		orders = new ArrayList<>();
	}

	public Long getCustomerId() {
		return customerId;
	}

	public void setCustomerId(Long customerId) {
		this.customerId = customerId;
	}

	public String getName() {
		return name;
	}

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

	public List getOrders() {
		return orders;
	}

	public void setOrders(List orders) {
		this.orders = orders;
	}

}

3. Create Message Model Classes


package com.javasampleapproach.ajaxhateoas.message;

public class Response {
	private String status;
	private Object data;

	public Response() {
	}

	public Response(String status, Object data) {
		this.status = status;
		this.data = data;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}
}

package com.javasampleapproach.ajaxhateoas.message;

public class Request {
	private Long customerId;
	private String order;

	public Request() {
	}

	public Request(Long customerId, String order) {
		this.customerId = customerId;
		this.order = order;
	}

	public Long getCustomerId() {
		return customerId;
	}

	public void setCustomerId(Long customerId) {
		this.customerId = customerId;
	}

	public String getOrder() {
		return order;
	}

	public void setOrder(String order) {
		this.order = order;
	}

}

4. Create Repository Class


package com.javasampleapproach.ajaxhateoas.repo;

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

import org.springframework.stereotype.Repository;

import com.javasampleapproach.ajaxhateoas.model.Customer;

@Repository
public class CustomerRepository {

	private final List customers = new ArrayList<>();

	public CustomerRepository() {
		this.customers.add(new Customer(1L, "Jack"));
		this.customers.add(new Customer(2L, "Adam"));
		this.customers.add(new Customer(3L, "Kim"));
	}

	public List findAll() {
		return this.customers;
	}

	public Customer findOne(Long id) {

		for (Customer customer : this.customers) {
			if (customer.getCustomerId().equals(id)) {
				return customer;
			}
		}
		return null;
	}
}

5. Create Controller Classes


package com.javasampleapproach.ajaxhateoas.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.javasampleapproach.ajaxhateoas.message.Request;
import com.javasampleapproach.ajaxhateoas.message.Response;
import com.javasampleapproach.ajaxhateoas.model.Customer;
import com.javasampleapproach.ajaxhateoas.model.Order;
import com.javasampleapproach.ajaxhateoas.repo.CustomerRepository;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;

import java.util.List;

@RestController
public class CustomerController {

	@Autowired
	private CustomerRepository repository;

	@RequestMapping(path = "/{id}")
	public Customer getCustomerById(@PathVariable Long id) {

		return this.repository.findOne(id);
	}

	@RequestMapping(path = "/{id}/orders")
	public List getOrdersForCustomer(@PathVariable Long id) {

		return this.repository.findOne(id).getOrders();
	}

	@RequestMapping(value = "/postorder", method = RequestMethod.POST)
	public Response postCustomer(@RequestBody Request request) {

		Customer customer = this.repository.findOne(request.getCustomerId());
		customer.getOrders().add(new Order(request.getOrder()));
		
		Response response = new Response("Done", customer);
		return response;
	}

	@RequestMapping(value = "/getcustomer/{id}", method = RequestMethod.GET)
	public Response getResource(@PathVariable Long id) {

		Customer customer = this.repository.findOne(id);
		
		customer.removeLinks();
		customer.add(linkTo(CustomerController.class).slash(customer.getCustomerId()).withSelfRel());
		customer.add(linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customer.getCustomerId()))
				.withRel("allOrders"));

		Response response = new Response("Done", customer);
		return response;
	}
}

package com.javasampleapproach.ajaxhateoas.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class WebController {

	@RequestMapping("/")
	ModelAndView home(ModelAndView modelAndView) {

		modelAndView.setViewName("home");

		return modelAndView;
	}
}

6. Configuration for JSP Page and Static Resources

Add these lines to application.properties file:


spring.mvc.view.prefix = /WEB-INF/jsps/
spring.mvc.view.suffix = .jsp

7. Add JSP Page and Javascript Files

Under src/main/webapp/WEB-INF/jsps folder, add:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
	<title>Spring Boot HATEOAS - POST-GET AJAX Example</title>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<script	src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
	<script src="/js/post.js"></script>
	<script src="/js/get.js"></script>
	<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
</head>
<body>
	<div class="container">
		<h1>POST/GET AJAX - HATEOAS</h1>      
	    <div id="postdiv" class="row">
	        <form id="orderForm" class="col-md-6">
	            <label>Customer ID</label>
	            <input type="text" id="customerid" class="form-control"/>
	            <br/>
	            <label>Order</label>
	            <input type="text" id="order" class="form-control"/>
	            <br/>
	            <button type="submit" id="postBtn" class="btn btn-primary">Submit</button>
	        </form>
	    </div>
	    <br/>
	    <div id="postResultDiv" class="row">
	    </div>
	    <br/>
	    <div id="getdiv" class="row">
	        <label>Customer ID</label>
	        <input type="text" id="customerid_get" class="form-control" style="width:100px;"/>
	        <br/>
	        <button id="getBtn">Get Customer</button>
	    </div>
	    <br/>
	    <div id="getResultDiv" class="row">
	    </div>

	</div>
</body>
</html>

Under src/main/webapp/js folder, add:


$( document ).ready(function() {
	
	var url = window.location;
	
	// SUBMIT FORM
    $("#orderForm").submit(function(event) {
		// Prevent the form from submitting via the browser.
		event.preventDefault();
		ajaxPost();
	});
    
    
    function ajaxPost(){
    	
    	// PREPARE FORM DATA
    	var formData = {
    		customerId : $("#customerid").val(),
    		order : $("#order").val()
    	}
    	
    	// DO POST
    	$.ajax({
			type : "POST",
			contentType : "application/json",
			url : url + "postorder",
			data : JSON.stringify(formData),
			dataType : 'json',
			success : function(result) {
				if(result.status == "Done"){
					$("#postResultDiv").html(
							"" + 
							"Post Successfully! Customer's Info: ID = " + result.data.customerId + " , " +
									"Name = " + result.data.name + " , " +
											"new Order = " + result.data.orders[result.data.orders.length - 1].name
							+ ""
							);
				} else {
					$("#postResultDiv").html("~~ Error");
				}
				console.log(result);
			},
			error : function(e) {
				alert("Error!")
				console.log("ERROR: ", e);
			}
		});
    	
    	// Reset FormData after Posting
    	resetData();

    }
    
    function resetData(){
    	$("#customerid").val("");
    }
})

$( document ).ready(function() {
	
	var url = window.location;
	
	// GET REQUEST
	$("#getBtn").click(function(event){
		event.preventDefault();
		ajaxGet();
	});
	
	// DO GET
	function ajaxGet(){
		
    	var customerId = $("#customerid_get").val();
		
		$.ajax({
			type : "GET",
			url : url + "getcustomer/" + customerId,
			success: function(result){
				if(result.status == "Done"){
					console.log("url: ", url);
					var links = result.data.links;
					
					$("#getResultDiv").html(
							"" + 
							"Customer: ID = " + result.data.customerId + " , " +
							"Name = " + result.data.name + "" + "
" ); $.each(links, function(i, link){ var _link = links[i].rel + ": " + links[i].href + "
"; $("#getResultDiv").append(_link) }); console.log(result); } else { $("#getResultDiv").html("Error"); console.log("Fail: ", result); } }, error : function(e) { $("#getResultDiv").html("Error"); console.log("ERROR: ", e); } }); } })

8. Run & Check Result

– Config maven build:
clean install
– Run project with mode Spring Boot App.
– Open Browser, enter URL:
http://localhost:8080/
spring-hateoas-ajax-post-get-browser

POST: fill customerID & Order
spring-hateoas-ajax-post-get-post-request

Press Submit, new line appears:
spring-hateoas-ajax-post-get-post-request-result

GET:
Fill customerID & press Get Customer button. Customer information with Links will appear:
spring-hateoas-ajax-post-get-request-result

Click Self Link:


{
   "customerId": 3,
   "name": "Kim",
   "orders": [
      {
         "name": "SmartPhone"
      }
   ],
   "_links": {
      "self": {
         "href": "http://localhost:8080/3"
      },
      "allOrders": {
         "href": "http://localhost:8080/3/orders"
      }
   }
}

Click Orders Link:


[{"name":"SmartPhone"}]

If we add new Order, for example: Tablet, then click Self Link:


{
   "customerId": 3,
   "name": "Kim",
   "orders": [
      {
         "name": "SmartPhone"
      },
      {
         "name": "Tablet"
      }
   ],
   "_links": {
      "self": {
         "href": "http://localhost:8080/3"
      },
      "allOrders": {
         "href": "http://localhost:8080/3/orders"
      }
   }
}

III. Source Code

SpringBootAjaxHATEOAS

One thought on “Spring HATEOAS Rest API + JQuery Ajax POST/GET example | Spring Boot”

Leave a Reply

Your email address will not be published. Required fields are marked *