Embora não haja suporte nativo para o consumo de webServices SOAP no Android (e também não seja uma prática recomendada pela Google), é possível fazê-lo.
Há uma infinidade de serviços online que utilizam o protocolo SOAP . Também, um grande número de empresas investiram tempo (e dinheiro) construindo conjuntos de serviços baseados nele.
Sendo assim, surgiu a necessidade de consumir SOAP em aplicativos Android. E, para nossa sorte, alguém um dia acordou inspirado e resolveu desenvolver uma biblioteca gratuita que permite fazer exatamente isso. Chama-se: KSOAP2 Library.
Este tutorial ensina a consumir um webService SOAP em um aplicativo Android.
Para começar, vamos escolher o serviço online que será consumido como exemplo. Utilizaremos um webService simples, de conversão de temperaturas, disponível no endereço abaixo:
O primeiro passo é descobrir quais os métodos disponíveis nesse webService, isto é, quais as operações que podemos executar a partir do consumo.
A pior maneira de fazer isto é abrindo o endereço acima no navegador e tentando descobrir através da leitura do WSDL. Uma maneira mais fácil é usar o software SoapUI, que já está disponível na pasta "@Android\Ferramentas" do nosso ambiente de desenvolvimento.
Vamos abrir o SoapUI e selecionar o menu "File", opção "New SOAP Project", para criar um novo projeto, conforme a figura:
http://www.w3schools.com/webservices/tempconvert.asmx?wsdl.
O nome do projeto aparecerá automaticamente. Depois, basta pressionar o botão "OK".
Ok! Cumprimos a primeira tarefa. Selecionamos um serviço online e, com a ajuda do SoapUI, conseguimos determinar o método que nos interessa (CelsiusToFarenheit) e seu argumento (Celsius). Precisaremos ainda do "namespace" do serviço, pois será necessário informá-lo ao KSOAP2. Para obter o namespace, basta, no SoapUI, clicar duas vezes sobre o nome do serviço, então uma janela com o namespace será mostrada, conforme a imagem:
Pronto! Já temos agora todo o necessário para iniciar um projeto de consumo do serviço SOAP pelo Android.
Vamos então criar um projeto no nosso ambiente de desenvolvimento chamado "consumidorSoap". O primeiro passo é incluir no projeto o arquivo JAR da biblioteca KSOAP2, que pode ser baixado clicando-se aqui. Se preferir obter uma versão mais recente, baixe diretamente do site do projeto KSOAP2, citado no início deste post.
Este arquivo deve ser colocado na pasta LIBS do projeto, conforme imagem:
O passo seguinte é criarmos o método que consome o serviço:
// Método que consome o webService.
public double converterCelsiusParaFarenheit(double grausCelsius)
{
// Define variável para armazenar o resultado.
double resultado=-1;
// Define o namespace, a URL do endpoint, e a ação do webService.
String NAMESPACE="http://www.w3schools.com/webservices/";
String URL = "http://www.w3schools.com/webservices/tempconvert.asmx?wsdl";
String END_POINT="http://www.w3schools.com/webservices/";
String METHOD_NAME="CelsiusToFahrenheit";
String SOAP_ACTION=END_POINT + METHOD_NAME;
// Define quantos milissegundos o KSOAP2 aguardará antes de considerar que a requisição falhou.
int timeout=20000;
// Declarações das variáveis necessárias para criar a requisição e transportá-la.
HttpTransportSE ht;
SoapObject request;
// Cria a requisição SOAP, para consumir o webService.
request=new SoapObject(NAMESPACE, METHOD_NAME);
// Cria o envelope.
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
// Acrescenta o parâmetro ao argumento do webService.
request.addProperty("Celsius", String.valueOf(grausCelsius));
// Insere a requisição montada no envelope.
envelope.setOutputSoapObject(request);
// Define o objeto que efetuará o transporte. Aqui também é definido o timeout.
ht=new HttpTransportSE(Proxy.NO_PROXY, URL, timeout);
try
{
// Efetivamente chama o consumo do webService.
ht.call(SOAP_ACTION, envelope);
// Extrai os elementos da resposta do webService.
String rs = "" + envelope.getResponse();
resultado=Double.parseDouble(rs);
}
catch (Exception e)
{
// Caso tenha ocorrido algum problema, indica a mensagem de erro no LogCat.
Log.i("consumidorSoap", "(MainActivity, método converterCelsiusParaFarenheit) erro: " + e.toString());
}
// Limpa os objetos instanciados, para liberar memória.
request=null;
envelope=null;
ht=null;
// Retorna o resultado.
return resultado;
}
A rotina acima consumirá o webService SOAP chamando o método remoto "CelsiusToFarenheit", passando um valor em graus Celsius e recebendo de volta uma resposta com o valor convertido em Farenheit.
Copie e cole o método na classe MainActivity.java.
Agora vamos criar a chamada ao método:
Primeiro vamos definir as variáveis, logo antes do método onCreate():
// Define as variáveis que guardarão os valores das temperaturas.
Copie e cole o método na classe MainActivity.java.
Agora vamos criar a chamada ao método:
Primeiro vamos definir as variáveis, logo antes do método onCreate():
// Define as variáveis que guardarão os valores das temperaturas.
private Double temperaturaEmFarenheit;
private Double temperaturaEmCelsius;
private String mensagem="";
Depois, no próprio método onCreate(), logo após o "setContentView", vamos adicionar o código:
// Chama o método para consumir o webService que converte de Celsius para Farenheit.
temperaturaEmCelsius=32.0;
temperaturaEmFarenheit = converterCelsiusParaFarenheit(temperaturaEmCelsius);
// Define a mensagem de saída.
if (temperaturaEmFarenheit > 0)
{
mensagem=temperaturaEmCelsius + "° Celsius = " + temperaturaEmFarenheit + "° Farenheit.";
}
else
{
mensagem="Não foi possível efetuar a conversão a partir do webService.";
}
// Mostra o resultado da conversão no LogCat.
Log.i("consumidorSoap", mensagem);
O passo seguinte é acrescentar a permissão de uso de Internet ao arquivo AndroidManifest.xml, sem a qual ganharíamos erro:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.consumidorsoap"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<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="com.example.consumidorsoap.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>
Também teremos que criar uma entrada no LogCat, a fim de visualizar as mensagens de debug advindas da execução do nosso código, pois não estamos mostrando nada na tela do dispositivo.
Basta selecionar o LogCat, na parte inferior central da janela do Eclipse e primeiro clicar no sinal de "+" verde. Na janela que se abre, digitar "consumidorSoap" nas duas primeiras linhas e depois clicar no botão "OK":
Pronto. Agora é só compilar o projeto e ver o resultado:
Quem preferir poderá baixar o código completo. É claro que este é um exemplo bem simples, consumindo um webService SOAP básico. Se for o caso do WSDL conter objetos complexos (complexTypes), a abordagem muda um pouquinho. Quem precisar de ajuda, estou à disposição. Ficamos por aqui. Espero que tenha sido proveitoso. Até o próximo post!
Boa tarde Luiz estou com erro ao executar um simples webservice (server) que fiz utilizando java. E ocorre o seguinte erro:android.os.NetworkOnMainThreadException .
ResponderExcluirMeu WSDL:
-------------------
String NAMESPACE="http://192.168.15.50:9876/";
String URL = "http://192.168.15.50:9876/guttyws?wsdl";
String END_POINT="http://192.168.15.50:9876/";
String METHOD_NAME="testar";
String SOAP_ACTION=END_POINT + METHOD_NAME;
Prezado, este é um erro muito comum no Android. Advém do fato de que você está tentando acessar a rede de dentro do MainActivity, de forma síncrona. No Android, você precisa acessar a rede de forma assíncrona, uma vez que não tem como saber quando receberá uma resposta. Você precisa colocar a chamada dentro de um Thread ou dentro de um AsyncTask. Aí vai funcionar!
ExcluirOlá Luiz! Muito boa a sua explicação.
ResponderExcluirEstou tentando consumir um webservice com alguns tipos complexos e várias funções.
Fazer "na mão", pelo que vi, é inviavel.
Você conhece algum jeito automático de se criar essa interface entre o webservice e a aplicação Android?
Olha... O KSoap tem algumas formas sofisticadas que permitem fazer isto, mas você teria que pesquisá-lo mais a fundo. Outra alternativa é utililar alguma linguagem que gere os STUBS do serviço, ou seja, você manda consumir o WSDL e ele gera as rotinas prontinhas pra você usar. Eu sei que o Java tem isso, ferramentas que geram os STUBS. Coldfusion também (pois funciona sobre Java). De posse desses stubs, você migra para o Android facilmente.
ResponderExcluirAlex, pesquise no Google sobre WSIMPORT.
ResponderExcluirValeu!
ExcluirVou pesquisar agora.
Muito obrigado!