Click here to Skip to main content
13,866,241 members
Click here to Skip to main content
Add your own
alternative version

Stats

10.9K views
2 bookmarked
Posted 6 Apr 2015
Licenced CPOL

Accessing a REST Based Database Backend From an Android App

, 6 Apr 2015
The objective of this article is to show a method for accessing a REST based database backend from an Android* app using MongoDB* and Spring IO*.

Editorial Note

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Intel® Developer Zone offers tools and how-to information for cross-platform app development, platform and technology information, code samples, and peer expertise to help developers innovate and succeed. Join our communities for Android, Internet of Things, Intel® RealSense™ Technology, and Windows to download tools, access dev kits, share ideas with like-minded developers, and participate in hackathon’s, contests, roadshows, and local events.

Table of Contents

  1. Introduction
  2. Tools Used
    1. Environment Setup
  3. Creating the Database
  4. Accessing the Database
    1. Setting up the Android Project & Permissions
    2. Parsing the JSON Response
    3. Manipulating the Database
  5. Summary

Introduction

As smartphone and tablet devices continue to grow in capabilities and popularity they are becoming a natural part of the everyday computing devices that we carry with us, know how to use, and rely on. This continues to provide opportunities for developers to innovate in software apps to take advantage of the unique portable platforms that mobile devices offer. Businesses are deploying tablet devices within their venues to enhance the customer experience and provide greater revenue opportunity. These devices have wireless connections that are capable of communicating to a backend server. A restaurant is an interesting example where tablet devices are being deployed to each table allowing the customer to browse the menu, order when they are ready, and pay their bill when they are finished. Having a centralized backend server that each tablet can communicate with allows for new opportunities in restaurant management, analytics, dynamic menus, and improved service. This article discusses a method for accessing a REST based database backend from an Android app. In particular, the first section of the article will discuss the tools used, environment setup, and how to create the restaurant database. The

Tools Used

When creating a proof of concept, having a flexible solution that allows you to get a server up and running quickly is desirable. The Spring IO platform is an open source solution that uses an Apache* Tomcat server and works with a variety of databases. Spring provides a framework that makes it easy to get an Android client and a Linux* server communicating over a REST interface. Components used for the server side consist of Ubuntu* Linux 14 for the operating system, MongoDB for the database, and the Spring IO platform for the REST service. The components used for the client side consist of Android Studio for the development IDE, the Spring REST Template API’s for talking to the server, the Jackson library for parsing the JSON response, and AVD for Android device emulation. Please see the links below to learn more about these components.

http://www.ubuntu.com/

http://www.mongodb.org/

http://spring.io/

http://spring.io/understanding/REST

http://tomcat.apache.org/

https://developer.android.com/sdk/installing/studio.html

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

http://wiki.fasterxml.com/JacksonHome

Environment Setup

To get the environment setup for the server and client sides, please follow the steps below to install Linux, packages, and Android Studio.

Install Ubuntu Linux 14 and connect to a local network.

http://www.ubuntu.com/download

Install packages from the terminal.

MongoDB

        sudo apt-get update

        sudo apt-get install –y mongodb-org

git

        sudo apt-get install git

gradle

        sudo apt-get install gradle

curl

        sudo apt-get install curl

java

        sudo add-apt-repository ppa:webupd8team/java
        sudo apt-get update
        sudo apt-get install oracle-java8-installer

Install Android Studio

https://developer.android.com/sdk/index.html

Creating the Database

The Spring starter project provides a nice starting point for creating a persistent backend with MongoDB that uses a http JSON interface for accessing the database. It is easy to create a restaurant database that contains menu items and prices. In addition, queries can be defined in a few lines of code. See the steps below for creating the database, creating the queries, and running the service.

Get the Spring starter project.

git clone https://github.com/spring-guides/gs-accessing-mongodb-data-rest.git

Change into the initial source directory.

cd gs-accessing-mongodb-data-rest/initial/src/main/java/hello

Create the Restaurant Object (Restaurant.java).

import org.springframework.data.annotation.Id;

public class Restaurant {

    @Id private String id;

    private String menuCategoryName;

    private String menuItemName;

    private String menuItemPrice;

    private Boolean isSpecial;

    private String specialmenuItemPrice;


    public String getmenuCategoryName() {

          return menuCategoryName;

    }

    public void setmenuCategoryName(String menuCategoryName) {

          this.menuCategoryName = menuCategoryName;

    }

    public String getmenuItemName() {

          return menuItemName;

    }

    public void setmenuItemName(String menuItemName) {

          this.menuItemName = menuItemName;

    }

    public String getmenuItemPrice() {

          return menuItemPrice;

    }

    public void setmenuItemPrice(String menuItemPrice) {

          this.menuItemPrice = menuItemPrice;

    }

    public Boolean getisSpecial(){

          return isSpecial;

    }

    public void setisSpecial(Boolean isSpecial){

          this.isSpecial = isSpecial;

    }

    public String getspecialmenuItemPrice(){

          return specialmenuItemPrice;

    }

    public void setspecialmenuItemPrice(String specialmenuItemPrice){

          this.specialmenuItemPrice = specialmenuItemPrice;

    }

}

Create the Restaurant Database Repository with Queries (RestaurantRepository.java).

The path of the database root on the server will be http://localhost:8080/menu. Two queries are defined in the interface below. findByMenuItemName allows searches by menuItemName. findByMenuCategoryName allows searches by menuCategoryName.

import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;

import org.springframework.data.repository.query.Param;

import org.springframework.data.rest.core.annotation.RepositoryRestResource;


@RepositoryRestResource(collectionResourceRel = "menu", path = "menu")

public interface RestaurantRepository extends MongoRepository {

    List findByMenuItemName(@Param("name") String name);

    List findByMenuCategoryName(@Param("name") String name);

}

Create the Application class (Application.java).

The application class shown below is the main entry point into the service and includes configuration for using Spring IO and MongoDB in the service.

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;


@Configuration

@EnableMongoRepositories

@Import(RepositoryRestMvcConfiguration.class)

@EnableAutoConfiguration

public class Application {

       public static void main(String[] args) {

              SpringApplication.run(Application.class, args);

       }

}

Change into the initial directory.

cd gs-accessing-data-mongodb/initial/

Build It with Gradle.

./gradlew build

Run the server.

java –jar build/libs/<project_name>.jar

Access the database.

curl http://localhost:8080/menu

View the JSON response.

In this example, the database contains a Tacos menu item:

{

    "_links" : {

    "self" : {

    "href" : "http://localhost:8080/menu{?page,size,sort}",

    "templated" : true

        },

    "search" : {

    "href" : "http://localhost:8080/menu/search"

        }

    },

    "_embedded" : {

    "menu" : [ {

    "menuCategoryName" : "Mexican",

    "menuItemName" : "Tacos",

    "menuItemPrice" : "$15",

    "isSpecial" : false,

    "specialmenuItemPrice" : "$7.50",

    "_links" : {

        "self" : {

            "href" : "http://localhost:8080/menu/5488c2ee44ae7e3fab758edd"

            }

        }

    } ]

},

    "page" : {

    "size" : 20,

    "totalElements" : 1,

    "totalPages" : 1,

    "number" : 0

    }

}

Accessing the Database

4.1. Setting up the Android project permissions & dependencies

Launch Android Studio and create a new project. Once the new project is created it is necessary to add the internet permission to the manifest, Spring Rest Template dependency, and Jackson JSON parsing dependency as shown below.

Add the Internet Permission to the manifest (AndroidManifest.xml).

<uses-permission android:name="android.permission.INTERNET">

Add the RestTemplate and Jackson library dependencies (build.gradle).

apply plugin: 'com.android.application'.

android {

    compileSdkVersion 21

    buildToolsVersion "21.1.1"


    defaultConfig {

        applicationId "com.example.test.myapplication"

        minSdkVersion 7

        targetSdkVersion 21

        versionCode 1

        versionName "1.0"

    }

    buildTypes {

        release {

            minifyEnabled false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }

    }

    packagingOptions {

        exclude 'META-INF/ASL2.0'

        exclude 'META-INF/LICENSE'

        exclude 'META-INF/license.txt'

        exclude 'META-INF/NOTICE'

        exclude 'META-INF/notice.txt'

    }

}

dependencies {

    compile 'com.android.support:appcompat-v7:+'

    compile fileTree(dir: 'libs', include: ['*.jar'])

    compile 'org.springframework.android:spring-android-rest-template:1.0.1.RELEASE'

    compile 'com.fasterxml.jackson.core:jackson-databind:2.3.2'

}

4.2. Parsing the JSON response

The app needs a way to understand the JSON response and be able to parse it. An approach is to create Java objects that will represent the response. The Jackson library is a convenient library that can be used to parse the JSON response and use the Java objects. To use this library, Jackson annotations are added to the Java objects. The Java objects can be manually created, but there is a handy tool out there that will assist with creating them for a given JSON response at http://www.jsonschema2pojo.org/. The Menu Class for this example is shown below with the Jackson annotations.

package com.example.test.myapplication;

import com.fasterxml.jackson.annotation.JsonAnyGetter;

import com.fasterxml.jackson.annotation.JsonAnySetter;

import com.fasterxml.jackson.annotation.JsonIgnore;

import com.fasterxml.jackson.annotation.JsonInclude;

import com.fasterxml.jackson.annotation.JsonProperty;

import com.fasterxml.jackson.annotation.JsonPropertyOrder;


import java.util.HashMap;

import java.util.Map;

    @JsonInclude(JsonInclude.Include.NON_NULL)

    @JsonPropertyOrder({

        "menuCategoryName",

        "menuItemName",

        "menuItemPrice",

        "isSpecial",

        "specialmenuItemPrice",

        "_links"

    })

public class Menu {

    @JsonProperty("menuCategoryName")

    private String menuCategoryName;

    @JsonProperty("menuItemName")

    private String menuItemName;

    @JsonProperty("menuItemPrice")

    private String menuItemPrice;

    @JsonProperty("isSpecial")

    private Boolean isSpecial;

    @JsonProperty("specialmenuItemPrice")

    private String specialmenuItemPrice;

    @JsonProperty("_links")

    private Links_ Links;

    @JsonIgnore

    private Map additionalProperties = new HashMap();


    @JsonProperty("menuCategoryName")

    public String getMenuCategoryName() {

        return menuCategoryName;

    }


    @JsonProperty("menuCategoryName")

    public void setMenuCategoryName(String menuCategoryName) { this.menuCategoryName = menuCategoryName; }


    @JsonProperty("menuItemName")

    public String getMenuItemName() {

    return menuItemName;

    }


    @JsonProperty("menuItemName")

    public void setMenuItemName(String menuItemName) {

        this.menuItemName = menuItemName;

    }


    @JsonProperty("menuItemPrice")

    public String getMenuItemPrice() {

        return menuItemPrice;

    }


    @JsonProperty("menuItemPrice")

    public void setMenuItemPrice(String menuItemPrice) {

        this.menuItemPrice = menuItemPrice;

    }


    @JsonProperty("isSpecial")

    public Boolean getIsSpecial() {

        return isSpecial;

    }


    @JsonProperty("isSpecial")

    public void setIsSpecial(Boolean isSpecial) {

        this.isSpecial = isSpecial;

    }


    @JsonProperty("specialmenuItemPrice")

    public String getSpecialmenuItemPrice() {

        return specialmenuItemPrice;

    }


    @JsonProperty("specialmenuItemPrice")

    public void setSpecialmenuItemPrice(String specialmenuItemPrice) { this.specialmenuItemPrice = specialmenuItemPrice; }


    @JsonProperty("_links")

    public Links_ getLinks() {

        return Links;

    }


    @JsonProperty("_links")

    public void setLinks(Links_ Links) {

        this.Links = Links;

    }


    @JsonAnyGetter

    public Map getAdditionalProperties() {

        return this.additionalProperties;

    }


    @JsonAnySetter

    public void setAdditionalProperty(String name, Object value) { this.additionalProperties.put(name, value); }

}

4.3. Manipulating the database

The database is accessed through a simple REST based http interface for doing primitive operations such as POST, PUT, GET, and DELETE. The RestTemplate provides a nice API for performing these operations in an AsyncTask allowing the app to stay responsive. The code snippets below show an example of how to access and manipulate the restaurant database.

Creating a RestTemplate instance and server path.

private RestTemplate rest = new RestTemplate();

private String url = "http://192.168.1.110:8080/menu/";

Enabling the Jackson library JSON parsing.

RestTemplate rest = new RestTemplate();

rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

Creating a Menu Item instance:

Menu myMenuItem = new Menu();

     myMenuItem.setMenuCategoryName("Mexican");

     myMenuItem.setMenuItemName("Tacos");

     myMenuItem.setMenuItemPrice("$15");

     myMenuItem.setIsSpecial(false);

     myMenuItem.setSpecialmenuItemPrice("$7.50");

Adding a new menu item to the database (POST)

Adding a new menu item is a POST operation that passes a new menu item to the task.

new Http_POST_Task().execute(myMenuItem);

private class Http_POST_Task extends AsyncTask {

    @Override

    protected Void doInBackground(Menu... menuItem) {

        try{

           rest.postForObject(url,menuItem[0],Restaurant.class);

        }

        catch (Exception e) {

            Log.e("MainActivity", e.getMessage(), e);

        }

        return null;

    }

}

Deleting a menu item from the database (DELETE).

Deleting a menu item is a DELETE operation that passes the menu item to the task for deleting.

new Http_DELETE_Task().execute(myMenuItem);

private class Http_DELETE_Task extends AsyncTask {

    @Override

    protected Void doInBackground(Menu... menuItem) {

        try {

            //DELETE

            String urlStr = menuItem[0].getLinks().getSelf().getHref();

            rest.delete(new URI(urlStr));

        }

        catch (Exception e) {

            Log.e("MainActivity", e.getMessage(), e);

        }

        return null;

    }

}

Searching for a menu item in the database (GET) Searching for a menu item performs the findByMenuItemName query to get the specified menu item:

try {

    myMenuItem = new Http_findByMenuItemName_Task().execute("Tacos").get();

    } catch (InterruptedException e) {

        e.printStackTrace();

    } catch (ExecutionException e) {

        e.printStackTrace();

    }

private class Http_findByMenuItemName_Task extends AsyncTask {

    @Override

    protected Menu doInBackground(String... menuItemName) {

        try {

            String queryURL = url+"search/findByMenuItemName?name="+menuItemName[0];

            Restaurant restaurant = rest.getForObject(queryURL, Restaurant.class);

            return restaurant.getEmbedded().getMenu().get(0);

        }

        catch (Exception e) {

            Log.e("MainActivity", e.getMessage(), e);

        }

        return null;

    }

}

Updating an existing menu item in the database (GET) (PUT).

Updating an existing menu item performs a GET query operation to get the existing menu item:

try {

    myMenuItem = new Http_findByMenuItemName_Task().execute("Tacos").get();

    } catch (InterruptedException e) {

        e.printStackTrace();

    } catch (ExecutionException e) {

        e.printStackTrace();

    }

The existing menu item is modified and then a PUT operation is performed.

    myMenuItem.setMenuCategoryName("Chinese");

    myMenuItem.setMenuItemName("Crab Puffs");

    myMenuItem.setMenuItemPrice("$7");

    myMenuItem.setIsSpecial(true);

    myMenuItem.setSpecialmenuItemPrice("$5");

    new Http_PUT_Task().execute(myMenuItem);

private class Http_PUT_Task extends AsyncTask<Menu,Void,Void> {

    @Override

    protected Void doInBackground(Menu... menuItem) {

        try {

            String urlStr = menuItem[0].getLinks().getSelf().getHref();

            rest.put(new URI(urlStr),menuItem[0]);

        }

        catch (Exception e) {

            Log.e("MainActivity", e.getMessage(), e);

        }

        return null;

    }

}

Summary

This article showed a method for accessing a REST based database backend from an Android app. The tools used and set up of the environment was first discussed. Creating an example restaurant database with queries using MongoDB and Spring IO was shown. The article concluded showing how to use the Spring IO framework in an Android app to parse the JSON response & manipulate the database.

++This sample source code is released under the Intel Sample Source License.

About the Author

Mike Rylee is a Software Engineer with Intel Corporation. He currently works on app enabling for Android.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Android on Intel
United States United States
Intel is inside more and more Android devices, and we have tools and resources to make your app development faster and easier.


You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190214.1 | Last Updated 6 Apr 2015
Article Copyright 2015 by Android on Intel
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid