Взаимодействие RESTful-сервиса с Spring for Android
Этот урок освещает процесс создания приложения, которое использует
Spring For Android
RestTemplate
для взаимодействия с MVC
RESTful web-сервисом.
Что вы создадите
Вы создадите Android-клиент, который взаимодействует с Spring RESTful web-сервисом. В частности, клиент будет взаимодействовать с сервисом, созданным в уроке Создание RESTful Web-сервиса.
Android-клиент будет доступен через Android эмулятор и будет взаимодействовать с сервисом через запрос на:
http://rest-service.guides.spring.io/greeting
Сервис будет отвечать JSON сообщением:
{"id":1,"content":"Hello, World!"}
Android-клиент будет отображать ID и содержимое в форме.
Что вам потребуется
- Примерно 15 минут свободного времени
- Android Studio
- Интернет соединение
Создание Android-проекта
Создайте в Android Studio новый проект. Если хотите, можете использовать проект
из каталога initial
и перейти к шагу Создание класса представления.
Когда вы закончите, то сможете сравнить ваш код с кодом из каталога complete
и
запустить клиент. Используйте "Rest" для приложения и имен модуля, а также
измените имя пакета на "org.hello.rest". Укажите местоположение вашего проекта и оставьте
остальные параметры как есть по умолчанию.
Следующий скрин отображает некоторые параметры для настройки иконок приложения. Оставьте как есть по умолчанию.
Следующий скрин отображает параметры для выбора типа используемого activity. Выберите "Blank Activity".
Последний скрин отображает некоторые каталоги для настроек activity, разметки и имени фрагмента. И снова оставьте как есть настройки по умолчанию и нажмите кнопку "Finish".
Когда вы создадите проект, вы увидите, что добавлены несколько файлов.
Для прохождения этого урока, вам предстоит отредактировать следующие файлы:
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
Создание Android Manifest
После того, как вы создали проект, AndroidManifest.xml
был
также создан в базовом исполнении. Android Manifest
содержит всю необходимую информацию для запуска Android-приложения и не может
быть собрано без него. Манифест также содержит любые разрешения, которые приложение
запрашивает у операционной системы Android. В нашем случае, приложению необходим
доступ к интернет для создания HTTP запросов.
Добавьте 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>
Создание строковых ресурсов
Текстовые строки могут ссылаться на файловые ресурсы как из приложения,
так и на другие источники. В этом уроке изпользуются четыре текстовых
представления и пункт меню, где каждый из этих UI элементов нуждается в тектовом
описании. Для начала, удалите строки hello_world
и
action_settings
. Они не используются в этом учебном материале,
поэтому могут быть удалены. Затем добавьте строки id_label
,
id_value
, content_label
, content_value
и
action_refresh
для каждого UI виджета на будущее.
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>
Создание разметки
Файл разметки является местом, где вы определяете визуальную структуру
пользовательсткого интерфейса вашего приложения. Когда вы создали проект,
Android Studio добавило фрагмент разметки. Как следует из названия, фрагмент
разметки представляет собой часть общей разметки. В нашем случае, фрагмент
разметки использован для отображения некоторого текста в главном activity.
Удалите существующий "Hello world" TextView
, который был добавлен
автоматически изначально при создании проекта. Затем измените фрагмент разметки,
включив в него четыре TextView
виджета.
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>
Разметка включает некоторую информацию о расположении и размере виджетов. Android Studio отображает визуальное представление разметки в окне предварительного просмотра:
Создание меню
Проект содержит меню для главного activity с существующим пунктом "Settings". Удалите этот пункт и добавьте пункт "Refresh". Обратите внимание, что для значения пункта меню также используется строковый ресурс.
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 отображает визуальное представление разметки в окне предварительного просмотра:
Создание класса представления
По медели JSON данных, полученных из RESTful HTTP запроса, вам необходимо создать класс представления, который определяет поля. Перейдите в "org.hello.rest" пакет из панели Project. Выберите "New..." из меню "File".
Выберите "Java Class"
Добавьте переменные id
и content
, а также их методы получения(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;
}
}
Добавление зависимостей
Чтобы использовать Spring for Android RestTemplate
,
вам необходимо добавить соответсвующие Maven зависимости в файл
сборки Gradle. RestTemplate
позволяет использовать
Jackson, мощный JSON обработчик для Java.
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'
}
Создание activity
Шаблон проектирования Model-View-Controller(MVC) широко используется
в Android приложениях. Activity
управляет представлением,
которое является разметкой, уже созданной вами. Когда вы создали проект,
MainActivity
было создано с реализацией по умолчанию. Измените
его, чтобы совершать RESTful HTTP запросы и обновлять представление.
Каждое изменение пояснено ниже.
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) {
// Заполнение меню; добавляются пункты меню в action bar, если он присутствует.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Это обработчик нажатия на пукт меню action bar. Аction bar будет
// автоматически обрабатывать нажатия Home/Up кнопки, до тех пор
// пока вы вы определите их действия в родительском activity в AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_refresh) {
new HttpRequestTask().execute();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Фрагмент, содержащий простое представление.
*/
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());
}
}
}
Для начала, добавьте частный класс HttpRequestTask
.
Этот класс наследуется от AsyncTask
, который
представляет собой механизм Android для выполнения потенциальных,
долговременных действий вне главного UI потока. Это очень важно,
т.к. иначе вы бы заблокировали UI, вынуждая пользователя поверить
в то, что приложение не отвечает или завершилось с ошибкой.
Spring предоставляет шаблонный класс RestTemplate
. Он
позволяет взаимодействовать с большинством RESTful сервисами. В
методе doInBackground
класса HttpRequestTask
,
RestTemplate
использован для создания HTTP запроса и
разбора JSON ответа в Greeting
объект. Когда
doInBackground
заканчивается, вызывается метод
onPostExecute
, в котором текстовые значения виджетов
greetingIdText
и greetingContentText
обновляются результатом HTTP запроса.
Далее, добавьте метод onStart
с вызовом метода
execute
класса HttpRequestTask
. Метод
onStart
является частью жизненного цикла Activity
и вызывается при запуске activity. В результате, HTTP запрос выполнится,
когда приложение загружается.
Напоследок, обновите метод onOptionsItemSelected
, чтобы также
выполнять HTTP запрос, когда пункт меню "Refresh" выбран. Это позволяет вам
совершать дополнительные HTTP запросы без необходимости закрывать и
перезапускать приложение.
Запуск клиента
Теперь вы можете запустить приложение из Android Studio. Для этого нажмите кнопку проигрывателя(зеленый треугольник) на панели инструментов Android Studio. Перед вами откроется диалоговое окно с выбором устройства, на котором будет запущено приложение. У вас должно быть Android-устройство, либо эмулятор, настроенный для запуска приложения. Если у вас нет настроенного Android Virtual Device (AVD), то вы можете выбрать кружочек для создания нового.
После выбора устройства, Android Studio соберет и развернет приложение:
ID значение будет увеличиваться каждый раз при нажатии кнопки обновления в меню.
Итог
Поздравляем! Вы только что разработали простой REST-клиент, используя Spring for Android.
С оригинальным текстом урока вы можете ознакомиться на spring.io.
comments powered by Disqus