Одной из задач, часто решаемых разработчиками мобильного софта, является получение данных от удаленного web сервиса. Этот процесс включает в себя несколько этапов: отправка запрос web-сервису, получение ответа и парсинг ответа с целью получения данных. В Android нет встроенного SOAP клиента, однако существует несколько довольно неплохих сторонних библиотек. Мы не будем пользоваться чужими поделками, а разработаем собственный клиент на базе Android API.
SOAP (Simple Object Access Protocol) это основанный на XML протокол, предназначенный для обмена данными между распределенными приложениями. REST (Representational State Transfer)- архитектура позволяющая строить распределенные, масштабируемые приложения. Основная задача сервера в этой архитектуре предоставить клиентам доступ к ресурсам по их идентификаторам (URI). Под доступом подразумевается как получение информации, так и ее изменение. SOAP и REST строятся поверх существующих web протоколов, например HTTP. Я не буду здесь вдаваться в детали, если Вы не знакомы с темой, рекомендую посмотреть вот эту статью.
Формат запроса для SOAP сервисуПрежде чем переходить к написанию кода, давайте посмотрим на структуру SOAP. Обычный SOAP запрос выглядит так: POST /InStock HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.w3schools.com/GetItems"
xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<m:Trans xmlns:m="http://www.w3schools.com/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>
<soap:Body>
<m:GetPrice xmlns:m="http://www.w3schools.com/prices">
<m:Item>Apples</m:Item>
</m:GetPrice>
</soap:Body></soap:Envelope> То есть SOAP запрос/ответ передается как пакет (SOAP Envelope), состоящий из заголовка (SOAP Header) и тела (SOAP Body).SOAP Header - вспомогательный компонент, содержащий конфиденциальную информацию для приложения, например параметры аутентификации. SOAP Body - это сообщение с полезной информацией. Заголовок может также содержать SOAP Action, который определяет функцию, запрашиваемую сервисом.
Отправка запроса SOAP-сервисуЧтобы вызвать SOAP-сервис вы должны сделать две вещи: Во-первых, вручную сконструировать SOAP пакет, например вот так: String envelope="xml version=\"1.0\" encoding=\"utf-8\"?>"+
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
"<soap:Body>"+
"<GetItems xmlns=\"http://tempuri.org/\">"+
"<startDate>%s</ startDate>"+
"<getAll>%s</getAll>"+
"</Items>"+
"</soap:Body>"+
"</soap:Envelope>"; где %s метка формата. С помощью метода String.format на ее место будет подставлятся конкретное значение. String requestEnvelope=String.format(envelope, "10-5-2011","true"); Во-вторых, вызвать web-сервис, например так: String CallWebService(String url,
String soapAction,
String envelope) {
final DefaultHttpClient httpClient=new DefaultHttpClient();
// параметры запроса
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 15000);
// устанавливаем параметры
HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);
// С помощью метода POST отправляем конверт
HttpPost httppost = new HttpPost(url);
// и заголовки
httppost.setHeader("soapaction", soapAction);
httppost.setHeader("Content-Type", "text/xml; charset=utf-8");
String responseString="";
try {
// выполняем запрос
HttpEntity entity = new StringEntity(envelope);
httppost.setEntity(entity);
// Заголоаок запроса
ResponseHandler<string> rh=new ResponseHandler<string>() {
// вызывается, когда клиент пришлет ответ
public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
// получаем ответ
HttpEntity entity = response.getEntity();
// читаем его в массив
StringBuffer out = new StringBuffer();
byte[] b = EntityUtils.toByteArray(entity);
// write the response byte array to a string buffer
out.append(new String(b, 0, b.length));
return out.toString();
}
};
responseString=httpClient.execute(httppost, rh);
}
catch (Exception e) {
Log.v("exception", e.toString());
}
// закрываем соединение
httpClient.getConnectionManager().shutdown();
return responseString;
}
После вызова этой функции Вы получите ответ, который будет виглядеть как-то так: <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <GetItemsResponse xmlns="http://tempuri.org/"> <GetItemsResult>
<Items> <Item> <name>string</name> <description>string</ description > </iPhoneCategory> <iPhoneCategory> <name>string</name> <description>string</ description > </ Item > </Items> </GetItemsResult> </ GetItemsResponse > </soap:Body> </soap:Envelope> Этот ответ нужно разобрать XML парсером и извлечь нужные данные.
Отправка запроса REST-сервисуРасбота с REST-сервисом намного проще. Вы должны вызвать сервис, передав ему URL с параметрами, например вот так:
http://example.com/resources/getitems
Пример вызова REST сервиса: String callWebErvice(String serviceURL){
// http get client
HttpClient client=new DefaultHttpClient();
HttpGet getRequest=new HttpGet();
try {
// создаем a URI объект
getRequest.setURI(new URI(serviceURL));
} catch (URISyntaxException e) {
Log.e("URISyntaxException", e.toString());
}
// Создаем BufferedReader дял чтения ответа
BufferedReader in=null;
// и HttpResponse для получения ответа
HttpResponse response=null;
try {
// выполняем запрос
response = client.execute(getRequest);
} catch (ClientProtocolException e) {
Log.e("ClientProtocolException", e.toString());
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
try {
in=new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
} catch (IllegalStateException e) {
Log.e("IllegalStateException", e.toString());
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
StringBuffer buff=new StringBuffer("");
String line="";
try {
while((line=in.readLine())!=null)
{
buff.append(line);
}
} catch (IOException e) {
Log.e("IO exception", e.toString());
return e.getMessage();
}
try {
in.close();
} catch (IOException e) {
Log.e("IO exception", e.toString());
}
// возвращаем ответ в виде строки текста
return buff.toString();
} Соединение с web-сервисом по протоколу Secure Sockets Layer (SSL)
HttpClinet не поддерживает SSL соединения, поэтому если Вам необходимо работать с защищенным web-сервисом, то используйте javax.net.ssl.HttpsURLConnection. Ниже приведен пример, иллюстрирующий работу с SSL SOAP web-сервисом. String CallWebService(String url,
String soapAction,
String envelope) throws IOException {
URL address=new URL(url);
URLConnection connection=address.openConnection();
HttpsURLConnection post=(HttpsURLConnection)connection;
post.setDoInput(true);
post.setDoOutput(true);
post.setRequestMethod("POST");
post.setRequestProperty("SOAPAction", soapAction);
post.setRequestProperty( "Content-type", "text/xml; charset=utf-8" );
post.setRequestProperty( "Content-Length", String.valueOf(envelope.length()));
post.setReadTimeout(4000);
OutputStream outStream=post.getOutputStream();
Writer out=new OutputStreamWriter(outStream);
out.write(envelope);
out.flush();
out.close();
InputStream inStream = post.getInputStream();
BufferedInputStream in = new BufferedInputStream(inStream,4);
StringBuffer buffer=new StringBuffer();
// читаем за раз 4 байта
byte[] buffArray=new byte[4];
int c=0;
while((c=in.read(buffArray))!=-1){
for(int i=0;i<c;i++)
buffer.append((char)buffArray[i]);
}
return buffer.toString();
} Итак, мы отправили запрос web-сервису и получили ответ в виде строки. Настало время использовать парсер.
Использование парсера в AndroidВ зависимости от реализации сервиса в ответ на наш запрос может прийти ответ в формате XML, SOAP или JSON. продолжение следует...
Источники: Android App Development: Calling Web Services Android App Development: Parsing Web Service Response part 1 Автор: Mina Samy Перевод: Александр Ледков Взято с http://www.mobilab.ru
|
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.