This Getting Started guide walks you through the process of building an application that uses Spring for Android's RestTemplate to consume a Spring MVC-based RESTful web service.

What you will build

You will build an Android client that consumes a Spring-based RESTful web service. Specifically, the client will consume the service created in Building a RESTful Web Servce.

The Android client will be accessed through an Android emulator, and will consume the service accepting requests at:

http://rest-service.guides.spring.io/greeting

The service will respond with a JSON representation of a greeting:

{"id":1,"content":"Hello, World!"}

The Android client will render the ID and content into a view.

What you will need

Create an Android project

Within Android Studio, create a new project. If you prefer, you can use the project in the initial folder and skip ahead to Create a representation class. When you are finished, you can compare your code to the complete folder and Run the client. Use "Rest" for the application and module names, and modify the package name to be "org.hello.rest". Enter the location of your choosing for the project and leave all the other options with their default settings.

Create new Project

The next screen presents some options for configuring the app icons. Continue with the default options.

Create new Project

The next screen presents an option to select the type of activity to use. Select "Blank Activity" and continue.

Create new Project

The last screen presents some fields for setting the activity, layout, and fragment names. Again, continue with the default options to finish the project setup.

Create new Project

When the project is created, you will see that several files are added.

View the Android project contents

To complete this guide, you will edit the following:

  • Rest/src/main/AndroidManifest.xml

  • Rest/src/main/res/values/strings.xml

  • Rest/src/main/res/layout/fragment_main.xml

  • Rest/src/main/res/menu/main.xml

  • Rest/build.gradle

  • Rest/src/main/java/org/hello/rest/MainActivity.java

Create an Android Manifest

When you created the project, an AndroidManifest.xml was also created with a basic implementation. The Android Manifest contains all the information required to run an Android application, and it cannot build without one. The manifest also contains any permissions for which the app is requesting of the Android operating system. In this case, the app needs to access the internet to make an HTTP request.

Add the INTERNET permission so the application can access resources over the internet.

Rest/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.hello.rest"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="19" />

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name="org.hello.rest.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Create string resources

Text strings can be referenced from the application or from other resource files. This guide uses four text views and a menu item, and each of these UI elements needs a text description. First, remove the hello_world and action_settings strings. When you created the project, it included these. These are not used for this guide and can be removed. Next, add id_label, id_value, content_label, content_value and action_refresh strings for each UI widget respectively.

Rest/src/main/res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Rest</string>
    <string name="id_label">The ID is</string>
    <string name="id_value">[id]</string>
    <string name="content_label">The Content is</string>
    <string name="content_value">[content]</string>
    <string name="action_refresh">Refresh</string>

</resources>

Create a layout

The layout file is where you define the visual structure for the user interface of your application. When you created the project, Android Studio added a layout fragment. As the name implies, a layout fragment represents a piece of the overall layout. In this case the layout fragment is used to display some text within the main activity. Remove the existing "Hello world!" TextView that was added when you created the project. Then modify the layout fragment to include four TextView widgets. The ids are used to reference these widgets from the code. Note the use of the string resources for the text of each widget.

Rest/src/main/res/layout/fragment_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity$PlaceholderFragment">

    <TextView
        android:id="@+id/id_label"
        android:text="@string/id_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/content_label"
        android:text="@string/content_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:layout_below="@+id/id_label"
        android:layout_alignParentLeft="true" />

    <TextView
        android:id="@+id/id_value"
        android:text="@string/id_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/id_label"
        android:layout_marginLeft="50dp" />

    <TextView
        android:id="@+id/content_value"
        android:text="@string/content_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/content_label"
        android:layout_alignLeft="@+id/id_value" />

</RelativeLayout>

The layout includes some information about how to position and size the widgets. Android Studio will display the visual representation of the layout in the preview window:

Fragment layout preview

Create a menu

The project includes a menu for the main activity with an existing "Settings" option. Remove the "Settings" menu option and add the "refresh" option. Note again the use of the string resource as the title of the menu item.

Rest/src/main/res/menu/main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity" >

    <item android:id="@+id/action_refresh"
        android:title="@string/action_refresh"
        android:orderInCategory="100"
        app:showAsAction="never" />
</menu>

Android Studio will display the visual representation of the menu in the preview window:

Fragment layout preview

Create a representation class

To model the JSON data received from the RESTful HTTP request, you create a representation class that defines the fields. Navigate to the "org.hello.rest" package in the Project navigator. Select "New…​" from the "File" menu.

Add new file

Select "Java Class"

Add new class

Add the id and content member variables and getters.

Rest/src/main/java/org/hello/rest/Greeting.java

package org.hello.rest;

public class Greeting {

    private String id;
    private String content;

    public String getId() {
        return this.id;
    }

    public String getContent() {
        return this.content;
    }

}

Add dependencies

To utilize Spring for Android’s RestTemplate within an Android app, you need to add the required Maven dependencies to the Gradle build file. RestTemplate makes use of Jackson, which is a powerful JSON processor for Java.

You may need to close and reopen Android Studio for Gradle to properly refresh the dependencies

Rest/build.gradle

apply plugin: 'android'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    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'
}

Create an activity

The Model-View-Controller design pattern (MVC) is used extensively in Android applications. An Activity controls the view, which is represented by the layout you already created. When you created the project, a MainActivity was also created with a default implementation. Modify the MainActivity to make a RESTful HTTP request and update the view. Each modification is explained below.

Rest/src/main/java/org/hello/rest/MainActivity.java

package org.hello.rest;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        new HttpRequestTask().execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_refresh) {
            new HttpRequestTask().execute();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
        }
    }


    private class HttpRequestTask extends AsyncTask<Void, Void, Greeting> {
        @Override
        protected Greeting doInBackground(Void... params) {
            try {
                final String url = "http://rest-service.guides.spring.io/greeting";
                RestTemplate restTemplate = new RestTemplate();
                restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
                Greeting greeting = restTemplate.getForObject(url, Greeting.class);
                return greeting;
            } catch (Exception e) {
                Log.e("MainActivity", e.getMessage(), e);
            }

            return null;
        }

        @Override
        protected void onPostExecute(Greeting greeting) {
            TextView greetingIdText = (TextView) findViewById(R.id.id_value);
            TextView greetingContentText = (TextView) findViewById(R.id.content_value);
            greetingIdText.setText(greeting.getId());
            greetingContentText.setText(greeting.getContent());
        }

    }

}

First, add the HttpRequestTask private class. This class inherits from AsyncTask which is a facility provided by Android for performing potentially, long running activities off of the main UI thread. It is important to do this, because otherwise you can lock the UI, causing a user to believe the app has stopped responding or crashed.

Spring provides a template class called RestTemplate. RestTemplate makes interacting with most RESTful services a simple process. Within the doInBackground method of the HttpRequestTask class, RestTemplate is used to make an HTTP request and marshal the JSON response to a Greeting object. When doInBackground returns, the onPostExecute method is called, where the text values of the greetingIdText and greetingContentText widgets are updated with the results of the HTTP request.

Next, add the onStart method which calls the execute method on HttpRequestTask. The onStart method is part of the Activity lifecycle and is called when the activity starts. The result is that the HTTP request is performed when the app loads.

Lastly, update the onOptionsItemSelected method to also execute the HTTP request when the "Refresh" menu item is selected. This allows you to make additional HTTP requests without closing and restarting the app.

Android Studio does not automatically update the imports, however you can change this behavior in the settings. Once enabled it will behave similarly to "Ctrl+Shift+O" in STS or Eclipse. Otherwise, you need to manually update the imports to include the newly referenced classes.

Enable automatic imports

Run the client

You can now run the app from Android Studio. To do this, click the play button (green triangle) in the toolbar of Android Studio. A dialog box will appear asking you to select the device on which to run the app. You must have an Android device or emulator configured in order to run the app. If you have not configured an Android Virtual Device (AVD), then you can select the elipsis to create a new one.

Choose Android device

After you select an Android device, Android Studio will build and deploy the app:

Model data retrieved from the REST service is rendered into the view

The ID value will increment each time you click the refresh menu button.

Model data retrieved from the REST service is rendered into the view

Summary

Congratulations! You have developed a simple REST client using Spring for Android.