2017  Kodetalk | Feedback | Privacy Policy | Terms | About
userimage

Spring REST Template Tutorial and Example by Consuming Quickblox Services

Overview

As we know now a days most of the IT industries started following Service Oriented Architecture. Because any new brand application started today may be going to serve(publishing its services) with multiple industries later. And we don't know that industry prefer which programming language to fulfill the client business. So to work on a single project with multiple industries simultaneously, SOA is the best solution for them with the mechanism of producing and consuming of the service to each other independently. 


And now a days to consume the published service or to produce the new service Spring plays a vital role with its RestTemplate APIs. It makes the world crazy to use with its simpleness and abstract behavior by undertaking the complexity himself. Here we will discuss about the mostly used HTTP method GET and POST to consume the services with a little additional flavor of PUT and DELETE method too. And learn how to consume the written services provided by third party vendors(like Quickblox) which actually going to use and benefited in real time applications.


Prerequisites

Before proceeding towards of this article I recommend to know about the RESTful web services and the programming approaches to understand easily. You can follow the post What exactly is RESTful programming? or from the Oracle official website What Are RESTful Web Services? for better understanding about RESTful Web Services. And register in Quickblox site Quickblox Registration for authenticating the service calls through them.


A short story on HTTP methods

The idea of SOA is either we can produce or consume the service from any end of the application. To fulfill this criteria compulsory we need to follow up with the HTTP methods. We have a huge number of HTTP methods are available like, GET, POST, PUT, DELETE, PATCH, COPY, HEAD, OPTIONS, LINK, UNLINK, PURGE, LOCK, UNLOCK, PROPFIND, VIEW. But your REST application might not support with all the methods. So before consume any REST service you can find the supported methods for your application. You can follow the link I want to figure out which methods are supported on a resource to know about the supported methods for your REST client and much more.


Brief of Common useful HTTP methods

        To Create a resource : HTTP POST should be used
        To Retrieve a resource : HTTP GET should be used
        To Update a resource : HTTP PUT should be used
        To Delete a resource : HTTP DELETE should be used


Sample program to consume the REST services using Quickblox RESTful services

Utility Class To generate quickblox signature

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.Formatter;
import java.util.Random;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class QuickBloxGenerateSignatureUtil {   
    static final String AUTH_SECRET = "xxx";

    public static String getSignatureDetails() {
        long timestamp = System.currentTimeMillis() / 1000L;
        int nonce = new Random().nextInt();
        String message = "application_id=appId&auth_key=authKey" + nonce + "&timestamp=" + timestamp;
        String hmac = null;
        try {
            hmac = calculateRFC2104HMAC(message, AUTH_SECRET);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return nonce + "," + timestamp + "," + hmac;
    }
    private static String calculateRFC2104HMAC(String data, String key) throws SignatureException,
            NoSuchAlgorithmException, InvalidKeyException {
        //HmacSHA1 is the name of an "HMAC-SHA" Algorithm
        SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(signingKey);
        return toHexString(mac.doFinal(data.getBytes()));
    }
    @SuppressWarnings("resource")
    private static String toHexString(byte[] bytes) {
        Formatter formatter = new Formatter();
        byte[] arrayOfByte = bytes;
        int j = bytes.length;
        for (int i = 0; i < j; i++) {
            byte b = arrayOfByte[i];
            formatter.format("%02x", new Object[] { Byte.valueOf(b) });
        }
        return formatter.toString();
    }
}


Service class with the implementation of common HTTP methods using RestTemplate API"s


import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class TestRestTemplateClient {
    
    private static final String APPLICATION_ID = "application_id";
    private static final String AUTH_KEY = "auth_key";
    private static final String NONCE = "nonce";
    private static final String TIMESTAMP = "timestamp";
    private static final String SIGNATURE = "signature";
    private static final String LOGIN = "login";
    private static final String PASSWORD = "password";
    
    private static final String QUICKBBLOX_LOGIN_ID = "xxx";
    private static final String QUICKBBLOX_LOGIN_PASSWORD = "xxx";
    
    private static final String QUICKBBLOX_APP_ID = "xxx";
    private static final String QUICKBBLOX_AUTH_KEY = "xxx";
    
    private static final String URL_GET_TOKEN = "https://api.quickblox.com/session.json";
    private static final String URL_LOGIN_USER = "http://api.quickblox.com/login.json";
    private static final String URL_SESSION_INFO = "http://api.quickblox.com/session.json";
    
    
    HttpHeaders headers = new HttpHeaders();
    RestTemplate restTemplate = new RestTemplate();
    
    //Method to invoke HTTP POST method by RestTemplate and get the authenticated token 
    public String getQuickBloxToken() throws JSONException {
        String[] signatureDetails = QuickBloxGenerateSignatureUtil.getSignatureDetails().split(",");
        JSONObject input = new JSONObject();
        input.put(APPLICATION_ID, QUICKBBLOX_APP_ID);
        input.put(AUTH_KEY, QUICKBBLOX_AUTH_KEY);
        input.put(NONCE, signatureDetails[0]);
        input.put(TIMESTAMP, signatureDetails[1]);
        input.put(SIGNATURE, signatureDetails[2]);
        String requestJson = input.toString();
        //specifying the content type - the service may JSON or XML type or any others
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("QuickBlox-REST-API-Version", "0.1.0");
        HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
        try {
            String response = restTemplate.postForObject(URL_GET_TOKEN, entity, String.class);
            if (response != null && !response.trim().isEmpty())
                return new JSONObject(new JSONObject(response).get("session")
                        .toString()).get("token").toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
    
    //Method to invoke HTTP POST method by RestTemplate and log in with Quickblox application through service call
    //establish a session
    public boolean loginQuickBlox(String token) throws JSONException {
        JSONObject jsonObj = new JSONObject();
        jsonObj.put(LOGIN, QUICKBBLOX_LOGIN_ID);
        jsonObj.put(PASSWORD, QUICKBBLOX_LOGIN_PASSWORD);
        String requestJson = jsonObj.toString();
        //specifying the content type - the service may JSON or XML type or any others
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("QuickBlox-REST-API-Version", "0.1.0");
        headers.set("QB-Token", token);
        HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
        try {
            String response = restTemplate.postForObject(URL_LOGIN_USER, entity, String.class);
            if ((response != null && !response.trim().isEmpty()) && !response.contains("errors"))
                return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    
    //Method to invoke HTTP GET method by RestTemplate and validate weather established session active or destroyed
    public boolean getCurrentSessionInfo(String token) {
        //specifying the content type - the service may JSON or XML type or any others
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("QuickBlox-REST-API-Version", "0.1.0");
        headers.set("QB-Token", token);
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        try {
            ResponseEntity<String> response = restTemplate.exchange(URL_SESSION_INFO, 
                    HttpMethod.GET, entity, String.class);
            if ((response != null && !response.getBody().trim().isEmpty()) 
                    && !response.getBody().contains("errors")) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    
    //Method to invoke HTTP DELETE method by RestTemplate and invalidate or destroyed the established session
    public boolean signOutCurrentUser(String token) {
        //specifying the content type - the service may JSON or XML type or any others
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("QuickBlox-REST-API-Version", "0.1.0");
        headers.set("QB-Token", token);
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        try {
            ResponseEntity<String> response = restTemplate.exchange(URL_LOGIN_USER, HttpMethod.DELETE, entity, String.class);
            if (response != null && response.hasBody()) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}


To learn more about Quickblox RESTful API's visit the official developers website http://quickblox.com/developers/Overview where you can learn how to get services from other industries which may publish it through public or private network.