воскресенье, 24 апреля 2016 г.

Взаимодействие с данными в Oracle MAF(ADF Mobile). Часть 3. Использование REST-JSON Web сервисов (Using REST-JSON Web Services in Oracle MAF)

Взаимодействие с данными в Oracle MAF(ADF Mobile). Часть 1. Использование SOAP-XML Web сервисов ( Using SOAP-XML Web Services in Oracle MAF)
Взаимодействие с данными в Oracle MAF(ADF Mobile). Часть 2. Работа с БД ( Work with DB in Oracle MAF)

Ранее я рассказывал как взаимодествовать с БД и SOAP-XML сервисами. В мобильных приложениях чаще всего используют REST-JSON сервисы,  и в этой статье я хочу рассказать как в MAF работать с ними. Приступим.
Что бы вызвать REST-JSON сервисы из MAF приложений , вы должны использовать RestServiceAdapter интерфейс .  Все что нужно для корректной работы интерфейса RestServiceAdapter это соединение к сервису. Для этого создайте REST или URL connection  в вашем MAF приложении. Я взял  открытый для общего доступа сервис http://jsonplaceholder.typicode.com



Вызов RestServiceAdapter  выглядит следующим образом :




где jsonplaceholder - имя ранее созданного соединения
       requestType - тип запроса(GET,PUT,POST,DELETE)
       requestUri - дополнительные параметры для запроса

В response  вернется строка в JSON формате. Что бы вывести результат на AMX странице, необходимо создать объект с такими же типами данных, которые должны вернуться. Для этого нужно создать Java Class и сгенерировать геттеры и сеттеры с галочкой  "Notify listeners when property change" , а так же создать DataControl  который  будет отвечать за обработку данных( вызов RestServiceAdapter  с необходимыми параметрами  и обработка данных)

В моём случае это :
Java класс :

Data control  класс:

package by.perevertkin.mobile.serviceresult.dc;
import by.perevertkin.mobile.serviceresult.ServiceResult;
import java.util.ArrayList;
import oracle.adfmf.dc.ws.rest.RestServiceAdapter;
import oracle.adfmf.framework.api.JSONBeanSerializationHelper;
import oracle.adfmf.framework.api.Model;
import oracle.adfmf.java.beans.PropertyChangeListener;
import oracle.adfmf.java.beans.PropertyChangeSupport;
import oracle.adfmf.java.beans.ProviderChangeListener;
import oracle.adfmf.java.beans.ProviderChangeSupport;
import oracle.adfmf.json.JSONArray;
import oracle.adfmf.json.JSONObject;
public class ServiceResultDC {
private ServiceResult[] serviceResults = null;
private ServiceResult serviceResult = null;
public ServiceResult[] getServiceResults() {
if (serviceResults == null) {
try {
String result = invokeRestJsonService(RestServiceAdapter.REQUEST_TYPE_GET, "/posts");
JSONArray inputArray = new JSONArray(result);
ArrayList resultsArray = new ArrayList();
for (int i = 0; i < 10; i++) {
try {
ServiceResult serviceResult = new ServiceResult();
JSONObject resultObject = inputArray.getJSONObject(i);
serviceResult.setTitle(resultObject.getString("title"));
serviceResult.setBody(resultObject.getString("body"));
serviceResult.setId(resultObject.getInt("id"));
resultsArray.add(serviceResult);
} catch (Exception e) {
}
}
serviceResults = (ServiceResult[]) resultsArray.toArray(new ServiceResult[resultsArray.size()]);
return serviceResults;
} catch (Exception e) {
System.out.println("Error getServiceResults:" + e.getLocalizedMessage());
}
}
return serviceResults;
}
public ServiceResult getPost(String id) {
try {
JSONBeanSerializationHelper jsonHelper = new JSONBeanSerializationHelper();
String result = invokeRestJsonService(RestServiceAdapter.REQUEST_TYPE_GET, "/posts/" + id);
serviceResult = (ServiceResult) jsonHelper.fromJSON(ServiceResult.class, result);
providerChangeSupport.fireProviderRefresh("serviceResult");
return serviceResult;
} catch (Exception e) {
System.out.println("Error get post:" + e);
}
return null;
}
public ServiceResult getServiceResult() {
return serviceResult;
}
private String invokeRestJsonService(String requestType, String requestUri) {
System.out.println("invokeRestJsonService---->" + requestType + " " + requestUri);
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
restServiceAdapter.setConnectionName("jsonplaceholder");
restServiceAdapter.setRequestType(requestType);
restServiceAdapter.setRetryLimit(0);
restServiceAdapter.setRequestURI(requestUri);
String response = "";
try {
response = restServiceAdapter.send("");
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
//***** provider change support *****//
//Enable provider change support
protected transient ProviderChangeSupport providerChangeSupport = new ProviderChangeSupport(this);
public void addProviderChangeListener(ProviderChangeListener l) {
providerChangeSupport.addProviderChangeListener(l);
}
public void removeProviderChangeListener(ProviderChangeListener l) {
providerChangeSupport.removeProviderChangeListener(l);
}
}
где :
  getServiceResults() - геттер переменной serviceResults, отвечающий за возвращение  всех данных из сервиса
  getPost(String id) - метод для получения данных для одного сообщения по id
  invokeRestJsonService(String requestType, String requestUri) - метод вызывающийся в  двух предыдущим методах для вызова сервиса

RestServiceAdapter возвращает данные с типом String в котором в зависимости то сервиса может находиться JsonArray или JsonObject. Если в возвращается JsonObject можно использовать вспомогательный класс JSONBeanSerializationHelper. У него есть метод fromJson, с помощью которого можно десериализовать строку из Json в Java(входящие параметры : Class type, String jsonString, где type - класс в который должен быть десереализован объект, jsonString- json объект)

Я создал приложение, в котором есть 2 amx страницы. На первой странице выводится список сообщений. И при нажатии на сообщение  загружается  вторая страница, в которой  выводятся детальные данные о сообщении.
Разработка не сильно отличается от ADF разработки, создаётся bounded task flow  в котором создается 2 страницы и view activity между ними.  Список создается простым перетягиванием с DataControl на amx страницу  необходимого атрибута. Результат :



Ссылка на исходники приложения в github: https://github.com/JealousyM/rest-json-maf
Так же  на  сайте Oracle есть подробное описание создания MAF приложения работающего с Rest-Json сервисом: http://docs.oracle.com/cd/E53569_01/tutorials/tut_jdev_maf_json/tut_jdev_maf_json.html