Acessando um web service SOAP no Android

Posted by rlecheta on outubro 23, 2013
Android, Tutorial

Olá,

No livro Google Android 3ª edição, aliás, desde a 1ª edição, foi explicado como utilizar o ksoap2 para acessar um web service.

O fato é que muitas vezes pode ser complicado acessar um web service com SOAP, por muitas razões, e tudo depende de como o web service foi criado.

Em um projeto, precisei acessar um web service SOAP, porém ele tinha regras específicas, e o ksoap não conseguia gerar o XML SOAP correto para enviar os dados.

A solução foi fazer um HTTP POST manual no web service. A única coisa que você precisa saber, é como enviar um XML SOAP no corpo da requisição.

Se você não conhece SOAP, obter esse XML é fácil, e uma das ferramentas mais úteis é o SOAP UI.

http://www.soapui.org/

O SOAP UI permite você configurar a URL do web service , os parâmetros e disparar a requisição para obter a resposta. E o melhor de tudo é que ele vai te mostrar exatamente a entrada que é o XML do SOAP, e o retorno, que também é um XML SOAP.

Para exemplificar vamos dar um exemplo, com este web service de tempo global.

http://www.webservicex.net/globalweather.asmx?WSDL
http://www.webservicex.net/globalweather.asmx

Web Services feitos em .Net são legais, pois já mostram o XML SOAP que você deve enviar.

6.003

E se você souber o XML do SOAP de entrada, basta utilizar uma simples classe para fazer o HTTP POST.

Mas para realmente testar o Web Service e ter certeza de que ele funciona, crie um projeto no SOAP UI.

6.001

O próprio SOAP UI vai exibir os serviços disponíveis e quando você clicar, ele mostra o XML de SOAP que você deve enviar.

Neste caso eu alterei para informar Brazil e Sao Paulo para receber as informações do tempo, e cliquei no botão Enviar.

Nos logs abaixo você pode verificar o XML SOAP correto. É este o cara que você precisa enviar!. Na direita está a resposta.

6.002

Note que nos logs também é possível visualizar o header http, e tem o parâmetro Content-type=Content-Type: application/soap+xml;charset=UTF-8;action=”http://www.webserviceX.NET/GetWeather.

Neste caso a Action é http://www.webserviceX.NET/GetWeather. Note que na figura 1 na descrição do web service ele já mostrava a Action.

Isso significa que ao fazer o POST é necessário enviar exatamente este cabeçalho no header.

6.004

Para testar a teoria, copie o XML do SOAP e a Action, e crie uma activity.

Deixei o XML de forma fixa para simplificar. Mas faça como achar melhor no seu projeto.

Exemplo:

————————————————————————

public class MainActivity extends Activity {

private static final String URL = "http://www.webservicex.net/globalweather.asmx";
protected static final String TAG = MainActivity.class.getSimpleName();

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

String xmlSoapEntrada =
"<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:web=\"http://www.webserviceX.NET\">"+
" <soap:Header/>"+
" <soap:Body>"+
" <web:GetWeather>"+
" <web:CityName>Sao Paulo</web:CityName>"+
" <web:CountryName>Brazil</web:CountryName>"+
" </web:GetWeather>"+
" </soap:Body>"+
"</soap:Envelope>";

String action = "http://www.webserviceX.NET/GetWeather";

AsyncTask<String, Void, String> task = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
try {
String xmlSoapEntrada = params[0];
String action = params[1];
final String soapXMLRetorno = HttpSoap.doPost(URL, xmlSoapEntrada,action);
return soapXMLRetorno;
} catch (Exception e) {
Log.e(TAG,e.getMessage(), e);
}
return null;
}

@Override
protected void onPostExecute(String xmlSoapRetorno) {
// fazer o parser aqui
Toast.makeText(getApplicationContext(), "OK ["+xmlSoapRetorno+"]", Toast.LENGTH_LONG).show();
}
};
task.execute(xmlSoapEntrada, action);
}
}

————————————————————————

E a classe que faz o POST é simples assim:

————————————————————————

public class HttpSoap {

/**
* @param url URL do web service
* @param soapXml XML SOAP de entrad
* @return XML soap de retorno
*
* @throws Exception
*/
public static String doPost(String url, String soapXml, String action) throws Exception {

// SOAP request send
HttpPost post = new HttpPost(url);
post.setEntity(new StringEntity(soapXml));
post.setHeader("Content-type", "application/soap+xml;charset=utf-8;action="+action);

HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(post);

// SOAP response(xml) get
String res_xml = EntityUtils.toString(response.getEntity());
return res_xml;
}
}

O resultado neste exemplo simples, é que o XML do SOAP de resposta será exibido na tela com um Toast.

print

Lembre-se. É isso que o ksoap faz por debaixo dos panos. Mas nada impede que você faça isso na mão.

Agora sempre que puder utilizar um framework e automatizar essa geração e parser do XML SOAP melhor.

abraços

 

Comments are closed.