Neste artigo
continuarei a falar sobre o assunto Web Services. Para quem leu o artigo do mês
passado com o título “Criando um Web Service utilizando o Eclipse Juno” veremos
que neste mês daremos uma continuação no que foi visto, utilizando como
ferramenta o Android com o auxílio de uma biblioteca de terceiros chamada
“KSOAP2”. Este artigo será bem prático, não envolvendo conceitos já citados em
outros artigos. Para ficar mais interessante iremos consumir um Web Service gratuito
para consulta de CEPS e Logradouros do Brasil. Então chega de papo e vamos por
a mão na massa.
Cadastrando no site
Iremos usar
como base para conhecimento o seguinte site:
O Serviço de consulta a
CEP é de uso livre. Sendo que atualmente trabalha com a base de CEP dos
Correios e contém mais de 811.000 logradouros cadastrados. A única
tarefa que devemos realizar seria um pequeno cadastro. Para isto, clique na
região superior direita “Área Usuário” e localize a opção “Criar Novo Usuário”.
Ver Imagem 01.
Figura 01: Criando o
usuário e senha.
Depois de
efetivar o cadastro, em alguns minutos receberá um e-mail para ativação de sua
conta. No primeiro contato ao entrar em sua área específica, receberá um aviso
idêntico aos dizeres a seguir:
“Para Utilizar os
serviços ByJG, você precisa ativar um serviço, selecione no menu acima o
serviço que deseja ativar”.
Localize no
menu acima a região chamada “Serviços CEP – CEP” e clique sobre a mesma.
Deveremos informar mais alguns dados adicionais para concluir e ativar o
serviço de Web Service. Ver Imagem 02
Figura 02:
Ativar Web Service de consulta de CEP.
Possuímos
diversos recursos como: Pesquisas (CEP e Logradouro), gráfico de utilização
entre outros.
Importante: O usuário e
senha serão utilizados ao decorrer do artigo.
Dados do Serviço
O endereço
do serviço é
Possuímos os
seguintes métodos ativos:
- string obterVersao( )
- Retorna a versão do WebService.
- string obterLogradouroAuth( string , string , string )
- Retorna o nome do logradouro à partir do CEP fornecido. Esse método
requer autenticação do usuário.
- string[] obterCEPAuth( string , string , string , string , string )
- Retorna o CEP à partir do nome do logradouro, localidade e unidade
federativa. Esse método requer autenticação de usuário. Se autenticado,
retorna as 20 primeiras linhas encontradas.
O endereço do
descritor do serviço WSDL é:
Adquirindo o framework “Ksoap2”
O framework
“Ksoap2” seria a ferramenta necessária para processar as mensagens SOAP. Ela
pode ser baixada diretamente pelo site:
Neste artigo recomendo utilizar a versão “2.5.8”.
Principais Classes
O framework
“Ksoap2” nos fornece todos os recursos necessários para consumir um Web Service.
Abaixo irei dar uma breve descrição das características destas classes.
1) org.ksoap2.serialization.SoapObject
Se caracteriza por ser um
objeto dinâmico simples que pode ser usado para construir as chamadas do
Ksoap2. Essencialmente, esta classe utiliza dois parâmetros, sendo: o
“namespace” (geralmente o endereço do WebService) e o “name” (o nome do método
a ser utilizado).
Exemplo de
utilização:
SoapObject soap = new SoapObject (namespace, name);
Os métodos:
- (SoapObject) envelope.bodyIn: Obter a resposta do serviço Web.
- getPropertyAsString(): Transformar
o resultado em variáveis do tipo Texto.
2) org.ksoap2.serialization.PropertyInfo
Essa classe é usada para
armazenar informações sobre cada propriedade do método a ser consumido do
webservice. Os métodos são:
- setName(): Nome da variável que
irá ser passada como parâmetro.
- setValue(): Valor que deverá ser
passado para a variável declarada anteriormente.
- setType(): Tipo de dados utilizado
na variável.
Para adicionar estas propriedades em nossa classe “SoapObject” criada
anteriormente deveremos implementar o método “addProperty()”.
Exemplo de
utilização:
PropertyInfo cepProp =new
PropertyInfo();
cepProp.setName("cep");
cepProp.setValue("18999999");
cepProp.setType(String.class);
soap.addProperty(cepProp);
3) org.ksoap2.serialization.SoapSerializationEnvelope
É uma classe que estende a
classe ”SoapEnvelop”
, com suporte para o formato “SOAP
Serialization”, que representa a estrutura de uma mensagem SOAP serializado. A
principal vantagem de serialização do SOAP é a portabilidade.
Exemplo
de utilização:
SoapSerializationEnvelope envelope = new
SoapSerializationEnvelope(SoapEnvelope.VER11);
A constante “SoapEnvelope.VER11” indica o SOAP versão
1.1. Faremos o uso de alguns métodos e propriedades, sendo:
- setOutputSoapObject (soap): Método responsável por
designar o objeto de solicitação “SoapObject” para o envelope como a
mensagem de saída referente à chamada de método de SOAP.
- dotNet: propriedade booleana para
definir a compatibilidade com o padrão de codificação .Net.
Exemplo de utilização:
envelope.dotNet
= true;
envelope.setOutputSoapObject(soap);
4) org.ksoap2.transport.HttpTransportSE
A classe “HttpTransportSE” representa uma camada “HttpTransport”
baseada em “J2SE. HttpTransportSE”,ela
estende a classe “org.ksoap2.transport.Transport”
, que resume a serialização e
desserialização das mensagens SOAP. Ao criar o objeto passamos como parâmetro a
URL, que seria o endereço para consumir o Web Service.
Exemplo de utilização:
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
Os métodos são:
- Call(SOAP_ACTION, envelope): responsável pela chamada usando como parâmetro o endereço do WebService + Método e o envelope SOAP.
Exemplo de utilização:
androidHttpTransport.call(SOAP_ACTION, envelope);
Criando o exemplo
No exemplo
deste artigo iremos envolver todos os conceitos aprendidos anteriormente. O
funcionamento deste exemplo será bem simples. Informaremos o CEP para nos
retornar o Endereço, Bairro, Cidade, Estado e Código IBGE. Para isto
descreverei todos os passos daqui pra frente.
Inicie uma aplicação do Zero clicando em “File/New/Android Project...” criando
uma classe chamada “ConsumindoWSActivity” para estender (extends) para a
interface “Activity” (Nesta classe é onde chamaremos a classe principal mais
adiante). Clique sobre o pacote e com o botão direito escolha “New/Class”
escolhendo o nome como CEP. (nesta classe onde criaremos todos os métodos
responsáveis pela consulta do CEP).
De imediato
teremos duas classes. Ver Figura 03 para maiores detalhes.
Figura 03: Classes do Projeto.
Importando a Biblioteca “Ksoap2”
Depois de ter conhecido um pouco sobre
este framework e de ter realizado o download, recomendo criar uma pasta chamada
“Libs” no projeto para melhor organização. É ali onde armazenaremos nossas
bibliotecas, que no caso seria apenas uma, a “ksoap2-android-assembly-2.5.8-jar-with-dependencies.jar”.
Para importá-la clique com o botão direito escolhendo a opção “Properties”. Em
“Java Build Path” localize a aba “Libraries”. Clique em “Add JARs...” para
adicioná-la ao projeto em questão. Ver Imagem 04.
Figura 04: Adicionado a Biblioteca
Ksoap2.
Teremos todas as classes necessárias
adicionadas ao projeto.
Classe “Cep.java”
O primeiro passo é importar as classes
utilizadas ao decorrer do desenvolvimento, veja abaixo:
package pct.ConsumindoWS;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class Cep
{
private static final String NAMESPACE =
"http://www.byjg.com.br/";
private static String URL = "http://www.byjg.com.br/site/webservice.php/ws/cep";
private static final String SOAP_ACTION =
"http://www.byjg.com.br/obterLogradouroAuth";
Teremos
três constantes, sendo:
NAMESPACE: O endereço do site que contém o Web Service.
URL: O endereço do serviço Web Service.
SOAP_ACTION: O endereço do site +
método utilizado.
public String[] ObterLogradouro(String Cep)
{
SoapObject soap = new SoapObject(NAMESPACE,
"obterLogradouroAuth");
String usuario = "usuario";
String senha = "senha";
PropertyInfo cepProp =new PropertyInfo();
cepProp.setName("cep");
cepProp.setValue(Cep);
cepProp.setType(String.class);
soap.addProperty(cepProp);
PropertyInfo usuarioProp =new PropertyInfo();
usuarioProp.setName("usuario");
usuarioProp.setValue(usuario);
usuarioProp.setType(String.class);
soap.addProperty(usuarioProp);
PropertyInfo
senhaProp =new PropertyInfo();
senhaProp.setName("senha");
senhaProp.setValue(senha);
senhaProp.setType(String.class);
soap.addProperty(senhaProp);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(soap);
HttpTransportSE
androidHttpTransport = new HttpTransportSE(URL);
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject result =
(SoapObject) envelope.bodyIn;
return result.getPropertyAsString(0).split(",");
}
catch (Exception e)
{
return null;
}
}
}
O método ObterLogradouro() tem como
parâmetro de entrada o Cep, uma variável do tipo String, e de saída uma
variável do tipo “Array of strings”, pois a mesma nos retorna os dados de
Endereço, Bairro, Cidade, Estado e Código IBGE. Instancie a classe “SoapObject”
passando como parâmetros as constantes (NAMESPACE e ObterLogradouroAuth).
Deixaremos como estático também as variáveis de autenticação Usuário e Senha
(Lembrando que estas informações foram adquiridas no início do artigo).
Criaremos três objetos do tipo “PropertyInfo” , sendo o CEP, Usuário e Senha.
Estas variáveis estão presentes no método “ObterLogradouroAuth()” . O método
“soap.AddProperty” está incluindo todos estes dados na classe “SoapObject”. O
Objeto “SoapSerializationEnvelope” representa a estrutura do SOAP, utilizaremos
ele para serializar os dados. Ao criar o objeto “HttpTransportSE” passamos como
parâmetro a URL, que seria o endereço para consumir o WebService comentado anteriormente.
Dentro do bloco “Try...Catch” obtemos o resultado transformado em um Vetor de
String.
Configurações no “AndroidManifest.xml”
A única alteração que não podemos esquecer-nos
de programar neste arquivo seria a permissão para acesso a internet. Veremos a
seguir o código necessário.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pct.ConsumindoWS"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ConsumindoWSActivity"
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>
Criando o “Lay-Out”
Usaremos 6
EditTexts, 6 TextViews e 1 Button para esta tela. Ver Imagem 05 uma sugestão
para nossa interface gráfica.
Figura 05: Lay-Out
Proposto.
O XML
correspondente:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout01">
<LinearLayout android:layout_width="185dp"
android:orientation="vertical"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout02">
<TextView android:layout_width="wrap_content"
android:text="CEP"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:id="@+id/txtCep">
</TextView>
<EditText android:id="@+id/edtCep"
android:layout_width="168dp"
android:layout_height="wrap_content"
android:inputType="number"
android:maxLength="8">
</EditText>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout03">
<TextView android:layout_width="wrap_content"
android:text=" "
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:id="@+id/TextView02">
</TextView>
<Button android:id="@+id/btnBuscar"
android:layout_width="90dp"
android:text="Buscar"
android:layout_height="wrap_content"
android:onClick="Buscar">
</Button>
</LinearLayout>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout04">
<TextView android:layout_width="wrap_content"
android:text="Endereço:"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:id="@+id/TextView04">
</TextView>
<EditText android:id="@+id/edtEndereco"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:editable="false"
android:enabled="false">
</EditText>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content"
android:id="@+id/linearLayout05">
<TextView android:layout_width="wrap_content"
android:text="Bairro:"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:id="@+id/txtBairro">
</TextView>
<EditText android:id="@+id/edtBairro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false">
</EditText>
</LinearLayout>
<LinearLayout android:orientation="vertical"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout06"
android:layout_width="248dp">
<TextView android:layout_width="wrap_content"
android:text="Cidade"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:id="@+id/txtCidade">
</TextView>
<EditText android:id="@+id/edtCidade"
android:layout_height="wrap_content"
android:layout_width="236dp"
android:enabled="false">
</EditText>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout07">
<LinearLayout android:orientation="vertical"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout08"
android:layout_width="154dp">
<TextView android:layout_width="wrap_content"
android:text="Estado"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:id="@+id/txtEstado">
</TextView>
<EditText android:id="@+id/edtEstado"
android:layout_height="wrap_content"
android:layout_width="110dp"
android:enabled="false">
</EditText>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content"
android:id="@+id/LinearLayout09">
<TextView android:layout_width="wrap_content"
android:text="Cód.
IBGE"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:id="@+id/txtCodIBGE">
</TextView>
<EditText android:id="@+id/edtCodIBGE"
android:layout_height="wrap_content"
android:layout_width="110dp"
android:enabled="false">
</EditText>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Codificando o exemplo (“ConsumindoWSActivity.java”)
Este é o
momento onde usaremos a classe CEP criada anteriormente. Importaremos algumas
bibliotecas básicas.
package pct.ConsumindoWS;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class ConsumindoWSActivity extends Activity
{
public EditText edtCep, edtEndereco, edtBairro,
edtCidade, edtEstado, edtCodIBGE;
Armazenaremos
o resultado nestas variáveis do tipo públicas.
@Override
public void onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
InicializaListeners();
}
public void InicializaListeners()
{
edtCep = (EditText) findViewById(R.id.edtCep);
edtEndereco = (EditText) findViewById(R.id.edtEndereco);
edtBairro = (EditText) findViewById(R.id.edtBairro);
edtCidade = (EditText) findViewById(R.id.edtCidade);
edtEstado = (EditText) findViewById(R.id.edtEstado);
edtCodIBGE = (EditText) findViewById(R.id.edtCodIBGE);
}
No
método “OnCreate()” Inicializaremos os “listeners“ atribuindo corretamente para
as variáveis. Recomendo sempre criar uma função para realizar este
procedimento.
public void Buscar(View v)
{
if (edtCep.getText().toString().length() == 8)
{
Cep cep = new Cep();
String[] resultado = cep.ObterLogradouro(edtCep.getText().toString());
try
{
edtEndereco.setText(resultado[0]);
edtBairro.setText(resultado[1]);
edtCidade.setText(resultado[2]);
edtEstado.setText(resultado[3]);
edtCodIBGE.setText(resultado[4]);
}
catch (Exception e)
{
edtBairro.setText("");
edtCidade.setText("");
edtEstado.setText("");
edtCodIBGE.setText("");
}
}
}
}
No método Buscar,
chamaremos o evento “Click” do Botão. Instancie a classe CEP e logo em seguida
invoque o método “ObterLogradouro()”. Passaremos como parâmetro o CEP
informado. Trataremos também o resultado dentro de um bloco Try..Catch. Teremos um resultado idêntico ao da Figura 06.
Exemplo em “Run-Time”
Figura 06:
Consulta de CEPs.
Referências
Conclusão
Aprendemos
neste artigo quais são as etapas para consumir um Web Service utilizando a
plataforma Android utilizando o Framework “Ksoap2”. Este WebService é
totalmente gratuito e possui outros métodos que podem ser consumidos, como por
exemplo: o ObterCepAuth(), que retorna o Cep a partir do logradouro,
localidade ou unidade federativa. Fiquem a vontade para usá-lo caso ache
necessário.
Espero que
tenham gostado um forte abraço e até o mês que vem!