×
Namespaces

Variants
Actions

Como usar Web Services em Java ME

From Nokia Developer Wiki
Jump to: navigation, search

Contents

Utilizando web services em aplicações móveis

Este artugo dá uma visão gerão da especificação JSR 172, que trata de Web Services em aplicações Java ME.

Link para o download do código-fonte completo do projeto Clima Global: Media:ClimaGlobal.zip

Introdução

Neste artigo, daremos uma breve introdução aos Web Services, tão falados na indústria de tecnologia de software hoje em dia, de sua aplicação na integração de serviços localizados remotamente, e principalmente sua relação com os dispositivos móveis, nosso foco neste artigo.

Após uma pequena introdução teórica e algumas informações conceituais, desenvolveremos uma aplicação chamada Clima Global, que fará uso da API de Web Services, presente nos dispositivos Nokia, para demonstrar como é fácil e rápido utilizar serviços desenvolvidos por terceiros para criar aplicações móveis realmente úteis para o dia-a-dia. Mãos à obra!

Desenvolvimento cliente-servidor e n-tier

Antigamente, para que um programa de computador pudesse ser compilado e executado corretamente, se fazia necessário que todo o seu código-fonte fosse digitado integralmente, como uma estória. Com a evolução das linguagens, tornou-se possível quebrar boa parte do código em funções, que podiam ser reutilizadas na construção do programa. Um pouco mais de evolução e as funções já podiam ser compiladas em módulos separados e linkadas com o executável final, permitindo não só a reutilização de código fonte mas também a do código compilado, sob a forma de bibliotecas. Como exemplo, temos as bibliotecas estáticas (arquivos .a) e dinâmicas (.so) em sistemas Unix e Linux, e as .dll (Dynamic Loading Library) no mundo Windows e também em sistemas móveis como o Symbian.

Com a expansão da área de informática e TI nas empresas, tornou-se necessária a criação de sistemas grandes e complexos, a serem instalados em centenas ou milhares de máquinas. Surgiu então o modelo cliente-servidor, que permitia a separação de código rodando nas máquinas clientes do rodando nas máquinas servidoras. No começo tal uso era restrito ao acesso a banco de dados (por exemplo, um cliente escrito em Delphi acessando um banco de dados Oracle que se localizava em um servidor remoto). Entretanto, a necessidade de separação acelerou-se desde que foi notado que muitos dos componentes de negócio (validação, cálculos de impostos, regras de negócios) também poderiam ser concentradas em um único servidor remoto, em vez de replicadas em partes de código instaladas em cada uma das máquinas acessando o sistema. A isto se chamou de arquitetura em 3 camadas (ou n camadas em caso de vários servidores em cadeia)

Com esta percepção, abriu-se espaço para os servidores de aplicação, os quais serviam como hospedeiros de componentes acessáveis pelos clientes instalados nas máquinas. Assim, se houvesse necessidade de corrigir ou substituir algum dos componentes de negócio, bastaria fazê-lo no servidor de aplicações e a alteração seria imediatamente visível nos clientes utilizadores de tal componente nas máquinas onde estivessem instalados. Isso garantia modularidade, facilidade de manutenção e atualização. Alguns dos servidores de aplicação mais famosos são: MTS (Microsoft Transaction Server), Weblogic, VisiBroker, entre muitos outros.

Apesar desta nova maneira de arquitetar e desenvolver aplicações ter trazido inúmeros benefícios, trouxe também sua parcela de problemas. O principal deles é a incompatibilidade entre protocolos: tais servidores utilizavam CORBA, DCOM, RMI entre tantos outros protocolos que, além de incompatíveis entre si, são em formato binário e utilizam portas não-padrões, o que causa inúmeros problemas com firewalls que filtram tais portas e mais ainda com os que filtram o conteúdo de pacotes binários que trafegam na rede.

Introdução aos Web Services

Para resolver ambos os problemas (incompatibilidade entre os protocolos, uso de portas e formatos binários rejeitados por firewalls), surgiu a idéia de Web Services. Web services são um sistema de software desenhado para permitir a comunicação machine-to-machine em uma rede de computadores; eles permitem a descrição de um serviço em uma determinada máquina, feita em uma linguagem baseada em XML (usualmente WSDL – Web Services Description Language). Tal descrição é feita seguindo-se as regras do padrão SOAP (Simple Object Access Protocol) para que, seguido o mesmo padrão, ferramentas do lado do cliente consigam automaticamente gerar código em linguagens como Java e as do framework .NET, para que do ponto de vista do desenvolvedor, ele esteja apenas acessando código em sua linguagem favorita, sem se importar com os detalhes como tráfego de rede, parsing do XML para consumo do serviço, etc. A Figura 1 nos mostra um exemplo simplificado da arquitetura de um web service:

Figura 1: Arquitetura básica de um Web Service

Figura 1: Arquitetura básica de um Web Service

Em suma, os principais benefícios dos Web Services são:

  • Protocolos baseados em um standard como XML, permitindo a geração automática tanto do código cliente quanto do código servidor.

Exemplo: um Enterprise JavaBean pode ser exposto como um web service de forma praticamente automática, e o código cliente em Java para consumi-lo pode ser gerado da mesma forma.

  • Utilização de protocolos baseados em texto, o que permite tráfego suave através de firewalls que fazem verificações de pacote.
  • Utilização de porta 80, do protocolo HTTP, o que permite transportar as chamadas ao serviço sem que o firewall bloqueie estas portas.</span></p>
  • Distribuição de código de forma modularizada e que permite fácil manutenção e correção de erros, sem os problemas verificados com as versões binárias de arquiteturas distribuídas.
  • Com a modularização atingida no item interior, torna-se possível que dispositivos de diferentes arquiteturas, como: computadores, handhelds, telefones celulares, set-top boxes, entre outros, consigam interagir e reutlizar serviços e porções de código possibilitando um uso mais inteligente e eficiente dos recursos computacionais.</span></p>


JSR 172 - Web Services no mundo Java ME

Para que uma plataforma seja habilitada a consumir Web Services, é necessário que possua suporte ao parsing de XML (afinal todas as trocas de mensagens são feitas neste padrão) e uma implementação do protocolo SOAP, para decodificar e “entender” a descrição do serviço, as operações disponibilizadas e os tipos de dados que elas retornam.

Para o mundo Java MicroEdition, essas pré-condições costumavam ser satisfeitas através do uso de pacotes de terceiros, tanto para o parsing de XML quanto para a decodificação dos envelopes SOAP. A Figura 2mostra alguns dos pacotes mais utilizados:

Figura 2: Pacotes de terceiros para parsing de XML e SOAP

Figura 2: Pacotes de terceiros para parsing de XML e SOAP

Pelo lado positivo, pacotes de terceiros trouxeram o poder de interpretar XML e SOAP a dispositivos que não tinham APIs para este fim. No caso dos dispositivos da Nokia, falamos de toda a geração Série 40 1a. e 2a. edições, e da S60 1a. e 2a Edições até Feature Pack 2. Isso significa que milhões de dispositivos já vendidos no mercado dependiam de os desenvolvedores integrarem frameworks XML junto com suas aplicações para ter a funcionalidade desejada. Enquanto esses frameworks funcionam bem e já foram suficientemente testados em aplicações comerciais, eles sofrem de três problemas básicos:

  • Precisam ser integrados diretamente ao pacote .JAR da aplicação, aumentando o tamanho da mesma e provocando problemas de instalação em dispositivos com menor quantidade de memória.
  • Não são implementados nativamente, o que faz com que sua performance não seja tão boa quanto a de componentes nativos.
  • Suas interfaces e APIs diferem bastante umas das outras, o que faz com que desenvolvedores utilizando mais de um desses parsers precisem manter versões diferentes de suas aplicações.

O desenvolvimento da especificação JSR 172 – Web Services API veio sanar todos esses problemas. A especificação descreve uma API unificada tanto para o parsing de XML quanto para o consumo do protocolo SOAP. Ela é composta de dois pacotes opcionais:

  • Um pacote para parsing de XML, consistindo em um subset do pacote JAXP 1.2 (Java API for XML Processing) encontrado na edição J2SE. Contém suporte apenas para um parser SAX (orientado a eventos) e suporta outros atributos como namespaces e diferentes encodings.
  • Um pacote para consumo de Web Services, consistindo em um subset do pacote JAX-RPC 1.1, que fornece a infraestrutura necessária para Web Services utilizando o modelo RPC com XML messages.

Ambos os pacotes possuem alguns tipos de limitação, que o leitor deverá procurar nos documentos relativos ao JSR 172, muitos deles podendo ser encontrados no site do Nokia Developer. Outro detalhe importante é que a implementação de ambos os pacotes é opcional, com alguns dispositivos implementando apenas o pacote de parsing enquanto outros implementam as duas sub-especificações. Para os dispositivos da Nokia, a opção de implementação está detalhada na Tabela 1:

Tabela 1: Implementação de JSR 172 em dispositivos Nokia
Dispositivo JSR 172 JSR 172 – XML Parsing JSR 172 – Web Services
Nokia Series 40 1ª. e 2ª. Edições Não - -
Nokia Series 40 3ª. Edição Sim Sim Não
Nokia Series 40 5ª. Edição Sim Sim Sim
Nokia S60 1ª. e 2ª. Edições até Feature Pack 2 Não - -
Nokia S60 2ª. Edição Feature Pack 3 Sim Sim Sim
Nokia S60 3ª. Edição – adiante Sim Sim Sim
Nokia Series 80 Não - (suporte via profile CDC) - -
Para verificar a qual plataforma pertence cada dispositivo, visite http://www.developer.nokia.com/Devices/


Para os dispositivos que ou não implementam JSR 172 ou sua parte opcional de consumo de serviços SOAP, a solução continua sendo usar parsers e implementações de terceiros. Entretanto, é uma tendência não só da Nokia quanto dos outros fabricantes de aumentar o número de dispositivos suportando JSR 172 por completo para facilitar a vida dos desenvolvedores.

A aplicação Clima Global – iniciando o desenvolvimento

Para nossa demonstração da facilidade de uso de Web Services através da JSR 172, desenvolveremos uma pequena aplicação, Clima Global, que nos possibilitará saber as condições climáticas em qualquer lugar do mundo. Como não temos tais dados disponíveis localmente, consultaremos um Web Service disponível na Internet que possui tais dados e os fará facilmente consultáveis por nossa aplicação.

Enquanto as quatro primeiras são ferramentas comumente usadas para o desenvolvimento de aplicações móveis, escolhi o SDK S60 3rd. Edition pelo fato de que os dispositivos Nokia S60 vendidos no mercado nacional dispõem de APIs poderosas para a escrita de aplicações sofisticadas em Java.

Após a instalação do JDK, do NetBeans e de seu Mobility Pack, é necessário instalar o SDK da Nokia, que contém o emulador no qual testaremos nossa aplicação. Após baixar o arquivo nS60_jme_sdk_3rd_e.zip, clique em setup.exe para iniciar a instalação. Aceite todos os defaults e a instalação será completada com sucesso. A seguir, configuraremos o NetBeans para que enxergue o SDK e o Wireless Toolkit recém-instalados.

  • Abra o NetBeans, e vá até a opção Tools / Java Platform Manager

Figura 3: Java Platform Manager

Figura 3: Java Platform Manager

  • Clique na opção marcada, e você verá a janela de seleção de plataformas. Clique sobre “J2ME”, e a seguir em “Add platform” e você verá uma caixa de seleção de tipo de plataforma a ser adicionada. Clique em “Java Micro Edition Platform Emulator” e você verá lista mostrada na na Figura 4.

Figura4.jpg

Figura 4: Seleção de emuladores a serem adicionados.

  • Selecione o SDK S60 3rd. Edition MIDP SDK e o Wireless Toolkit 2.5 (WTK 2.5) e ignore os demais SDKs, já que não iremos utiliza-los. Clique em “Next” e depois em “Finish” e seu ambiente estará configurado com os dois novos emuladores.

Criando um novo projeto

Criaremos um novo projeto para nossa aplicação Clima Global. Este projeto utilizará principalmente o SDK S60 3rd. Edition mas com algumas funcionalidades do Wireless Toolkit, tais como a geração de stubs e código-fonte para consumo de web services.

Para criar um novo projeto, clique em “File /New Project” e siga o roteiro detalhado abaixo:

<o:p> </o:p>

Figura5 uws.jpg

Figura 5: Criação de novo projeto de aplicação móvel

  • Clique em “Next”

Figura6 uws.jpg

Figura 6: Definição de nome e localização do projeto

  • Desmarque a opção “Create Hello MIDlet”, pois do contrário o NetBeans criará um esqueleto de aplicação “Hello World”, o que não nos interessa já que criaremos nosso próprio MIDlet do início. Clique em “Next”.

Figura7 uws.jpg

Figura 7: Definição de plataforma

  • Na próxima janela, mostrada na Figura 7, defina o SDK S60 3rd. Edition

como o emulador principal de sua aplicação, já que ele será o utilizado para rodar nossa aplicação. Clique em “Next” e depois em “Finish”, para finalizar nossa configuração.

Desenvolvendo o código

Agora que já temos nosso projeto configurado, é hora de colocar a mão na massa e começar a codificar. Clique com o botão direito sobre o projeto ClimaGlobal, escolha “New -> MIDlet”. Preencha os dados necessários à criação do midlet de acordo com o que está na Figura 8 e clique em “Finish”:

Figura8 uws.jpg

Figura 8: Criação do midlet principal

  • Crie as demais classes componentes do midlet com os parâmetros mostrados na Tabela 2.
  • Faça o download do código-fonte da aplicação abaixo, e

preencha os esqueletos gerados pelo NetBeans com o código real do midlet. Não discutiremos o código dessas classes, visto que ele é basicamente composto de classes de interface gráfica e rede, seguindo as práticas normais de programação em Java, e não estão no foco deste artigo, que é o estudo da utilização da nova JSR 172.</span></p>

Tabela 2: Criação das demais classes
Class Name Project Location Package
ErroForm ClimaGlobal SourcePackages exemplo.climaglobal.view
EsperaConexaoAlert ClimaGlobal SourcePackages exemplo.climaglobal.view
ResultadoForm ClimaGlobal SourcePackages exemplo.climaglobal.view
View ClimaGlobal SourcePackages exemplo.climaglobal.view
ConversorRespostaXML ClimaGlobal SourcePackages exemplo.climaglobal.modelo
Modelo ClimaGlobal SourcePackages exemplo.climaglobal.modelo
ConectorWebService ClimaGlobal SourcePackages exemplo.climaglobal.rede


Notificador ClimaGlobal SourcePackages exemplo.climaglobal.rede


ConectorWebService ClimaGlobal SourcePackages exemplo.climaglobal.rede

Uma vez criados os esqueletos de classes de rede, interface gráfica e de dados, vamos à parte mais importante de nossa aplicação: a criação do código de consumo do web service. Como dito anteriormente, essa é a parte mais fácil, pois todo o trabalho é automatizado pelas ferramentas de geração de código cliente, o que livra o desenvolvedor da necessidade de entender cada detalhe da implementação do serviço e de seu empacotamento no protocolo SOAP.

  • Clique com o botão direito sobre o nome do projeto (“Clima Global”), selecione “New” e “J2ME Web Service Client”, conforme a Figura 9.

Figura9 uws.jpg

Figura 9. Acessando o gerador de código para consumo de Web Services.

  • Ao selecionar a opção “J2ME Web Service Client”, você verá a janela seguinte, mostrada na Figura 10. Preencha os parâmetros conforme a figura:

Figura10 uws.jpg

Figura 10. Gerando código Java a partir de um arquivo de descrição de Web Services - WSDL

Você precisa prestar muita atenção pois há uma seqüência correta de procedimentos nesta janela:

    • Primeiro, preencha o parâmetro

WSDL URL com o endereço http://www.webservicex.net/globalweather.asmx e clique em Retrieve WSDL

    • Isto preencherá alguns dos

outros parâmetros. Substitua-os pelos parâmetros preenchidos acima para que o código gerado se adeque ao nosso projeto e compile adequadamente.</span></p>

    • Desmarque a caixa de texto “Create Sample MIDlet”, pois o nosso midlet já foi criado anteriormente e não há necessidade de faze-lo novamente. Clique em “Finish” e o código será gerado no local correto. Você terá seu projeto organizado de forma parecida ao da Figura 11: </span></p>

Figura11 uws.jpg

Figura 11. Projeto após a geração de código consumidor de Web Services

Estudo do código

Uma vez que o código para consumo do Web Service tenha sido gerado automaticamente, graças à padronização trazida pela JSR 172 e conseqüente construção de ferramentas de geração de código baseadas neste padrão, é hora de estudar o uso correto do mesmo para obter os dados desejados por sua aplicação.

Voltando ao NetBeans, vamos inspecionar o

conteúdo do pacote
exemplo.webservice
. Ele contém algumas classes, que dividirei em dois grupos:</span></p>
  • GetCitiesByCountry
  • GetCitiesByCountryResponse
  • GetWeather
  • GetWeatherResponse

Estas representam os elementos (tipos de dados) expostos pelo web service, traduzidos para código Java. O segundo grupo é composto das seguintes classes:</span></p>

  • GlobalWeatherSoap
  • GlobalWeatherSoap_Stub</span></p>

Estas contém o código para interpretação do protocolo SOAP, construção das mensagens enviadas para o serviço e recepção das mensagens vindas do servidor.

Mas como os dois grupos trabalham juntos? As classes do primeiro grupo podem ser utilizadas para o retorno de tipos complexos (por exemplo, uma lista ou vetor de objetos “Cidade”) para as nossas chamadas remotas de método. Vejamos um exemplo na Listagem 1.

Listagem 1. Classe de tipo de dados GetCitiesByCountry

//This class was generated by the JAXRPC SI, do not edit.
//Contents subject to change without notice.
//JSR-172 Reference Implementation wscompile 1.0, using: JAX-RPC Standard
Implementation (1.1, build R59)
 
package exemplo.webservice;
 
public class GetCitiesByCountry {
protected java.lang.String countryName;
 
public GetCitiesByCountry() {
 
public GetCitiesByCountry(java.lang.String countryName) {
this.countryName = countryName;
}
 
public java.lang.String getCountryName() {
return countryName;
}
 
public void setCountryName(java.lang.String countryName) {
this.countryName = countryName;
}
}

Entretanto, o uso das classes do grupo 1 não será necessário em nossa aplicação, visto que todas as operações estão descritas como retornando Strings e não tipos complexos. Porém, alguns pequenos ajustes na descrição WSDL e no código-cliente e seria fácil fazer o código gerado retornar objetos Java mais complexos do que uma String, diretamente para uso com chamadas a propriedades e métodos.

Nas classes do segundo grupo temos uma interface, GlobalWeatherSoap, que contém os métodos que chamaremos em nossa aplicação.

A classe GlobalWeatherSoap_Stub implementa esta interface provendo a estrutura necessária para a comunicação de rede, implementação de envio e recebimento de mensagens SOAP, e tradução dos resultados para a classe Java correta, no caso, String, visto que o serviço retorna um string XML com os dados do clima da cidade pesquisada. Esta classe faz todo o “trabalho duro” de comunicação e empacotamento, como podemos ver pelo trecho na Listagem 2.

Listagem 2. Classe GlobalWeatherSoap_Stub (abreviada)

//This class was generated by 172 StubGenerator.
//Contents subject to change without notice.<o:p></o:p></span></p>
//@generated
 
package exemplo.webservice;
 
public class GlobalWeatherSoap_Stub implements exemplo.webservice.GlobalWeatherSoap, javax.xml.rpc.Stub {
 
private String[] _propertyNames;
private Object[] _propertyValues;
 
public GlobalWeatherSoap_Stub() {
_propertyNames = new String[] {ENDPOINT_ADDRESS_PROPERTY};
_propertyValues = new Object[] {"http://www.webservicex.net/globalweather.asmx"}
}
 
//Begin user methods
//
 
public java.lang.String getWeather(java.lang.String cityName, java.lang.String countryName) throws java.rmi.RemoteException {
 
// Copy the incoming values into an Object array if needed.
Object[] inputObject = new Object[2];
inputObject[0] = cityName;
inputObject[1] = countryName;
 
Operation op = Operation.newInstance(_qname_GetWeather, _type_GetWeather, _type_GetWeatherResponse);
_prepOperation(op);
op.setProperty(Operation.SOAPACTION_URI_PROPERTY, "http://www.webserviceX.NET/GetWeather");
 
Object resultObj;<o:p></o:p></span></p>
try {
resultObj = op.invoke(inputObject);
}
catch (JAXRPCException e) {
Throwable cause = e.getLinkedCause();
if (cause instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException) cause;
}
throw e;
}
 
java.lang.String result;
// Convert the result into the right Java type.
// Unwrapped return value
 
Object getWeatherResultObj = ((Object[])resultObj)[0];
result = (java.lang.String)getWeatherResultObj;
return result;<o:p></o:p></span></p>
}
 
public java.lang.String getCitiesByCountry(java.lang.String countryName) throws java.rmi.RemoteException {
// Copy the incoming values into an Object array if needed.
Object[] inputObject = new Object[1];
inputObject[0] = countryName;
 
Operation op = Operation.newInstance(_qname_GetCitiesByCountry, _type_GetCitiesByCountry, _type_GetCitiesByCountryResponse);
_prepOperation(op);
op.setProperty(Operation.SOAPACTION_URI_PROPERTY, "http://www.webserviceX.NET/GetCitiesByCountry");
 
Object resultObj;
try {
resultObj =
op.invoke(inputObject);
}
catch (JAXRPCException e) {
Throwable cause =
e.getLinkedCause();
if (cause instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException) cause;
}
throw e;
}
 
java.lang.String result;
 
// Convert the result into the right Java type.
// Unwrapped return value>
Object getCitiesByCountryResultObj = ((Object[])resultObj)[0];
result = (java.lang.String)getCitiesByCountryResultObj;
return result;
 
}
 
// End user methods>
}

Logo, podemos perceber que todo o trabalho árduo já foi feito para nós desenvolvedores, então basta que chamemos os métodos correspondentes da classe stub para que tenhamos os dados desejados. Em nossa aplicação, isto é feito pela classe ConectorWebService, listada abaixo:

Listagem 3. Classe ConectorWebService>

package exemplo.climaglobal.rede;
 
import exemplo.webservice.GlobalWeatherSoap;
import exemplo.webservice.GlobalWeatherSoap_Stub;
 
/**
* Classe Runnable responsável por chamar os métodos
do web service
* Global Weather. Deve ser executada em um
novo Thread, para não bloquear
* a interface gráfica com o usuário.
*
*/

 
public class ConectorWebService implements Runnable {
 
//Variáveis de instância>
private String cidade = null;
private String pais = null;
private Notificador notificador = null;
 
/**
* Construtor da classe.>
*
* @param cidade
* @param pais
* @param notificador
*/

 
public ConectorWebService(String cidade, String pais, Notificador notificador) {
 
this.cidade = cidade;
this.pais = pais;
this.notificador = notificador;
}
 
/**
* Consulta o webservice e notifica o observador para essa operação.
*/

 
public void run() {
try {
GlobalWeatherSoap stub = new GlobalWeatherSoap_Stub();
String resultado = stub.getWeather(cidade,pais);
notificador.notificaResultado(resultado);
}
catch(Exception e) {
notificador.notificaExcecao(e);
}
}
}

Você pode notar que a chamada ao método GetWeather, realizada no objeto GlobalWeatherSoap, ocupa apenas oito linhas de código, não sendo necessário nenhum conhecimento ou uso das bibliotecas SOAP e XML, o que facilita em muito ao desenvolvedor se concentrar na funcionalidade da aplicação em vez dos mecanismos internos de funcionamento da mesma.

O valor retornado pelo método GetWeather é um string XML com o seguinte formato:

Listagem 4. String XML com dados do clima

<?xml version="1.0" encoding="utf-16"?>
<CurrentWeather>
 
<Location>
<st1:place w:st="on">
<st1:City w:st="on">Helsinki-Vantaa</st1:City>,
<st1:country-region w:st="on">Finland</st1:country-region>
</st1:place>
(EFHK) 60-19N 024-58E 56M
</Location>
 
<Time>Aug 22, 2007 - 04:50 PM EDT /2007.08.22 2050 UTC</Time>
 
<Wind> Variable at 2 MPH (2KT):0</Wind>
 
<Visibility> greater than 7 mile(s):0</Visibility>
 
<SkyConditions> partly cloudy</SkyConditions>
 
<Temperature> 60 F (16C)</Temperature>
 
<DewPoint> 59 F (15C)</DewPoint>
 
<RelativeHumidity> 93%</RelativeHumidity>
 
<Pressure> 30.09 in. Hg (1019 hPa)</Pressure>
 
<Status>Success</Status>
 
</CurrentWeather>

Para converter os dados, utilizamos o parser de XML também fornecido pelo JSR 172. Em nossa aplicação, o trabalho é feito pela classe ConversorRespostaXML. Como você pode ver na listagem abaixo, trata-se basicamente do mesmo mecanismo usado em JAXP para a versão desktop do Java, o que facilita muito o porte de aplicações entre as plataformas, e mais importante, fornece uma API padrão que não varia de aparelho para aparelho.</p>

Listagem 5. Convertendo dados do clima utilizando o parser SAX (abreviado)

package exemplo.climaglobal.modelo;
 
import java.util.Hashtable;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
 
/**
* Faz o parsing do XML e retorna em formato Nome/Valor.
*/

 
public class ConversorRespostaXML extends DefaultHandler {
 
private static Hashtable portugueseData = new Hashtable();
private Hashtable data = new Hashtable();
private String tagAtual = null;
private String valorAtual = "";
 
static {
portugueseData.put("Location","Localização");
portugueseData.put("Time","Hora e Data");
portugueseData.put("Wind","Vento");
portugueseData.put("Visibility","Visibilidade");
portugueseData.put("SkyConditions","Céu");
portugueseData.put("Temperature","Temperatura");
portugueseData.put("DewPoint","Orvalho");
portugueseData.put("RelativeHumidity","Umidade");
portugueseData.put("Pressure","Pressão");
}
 
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
tagAtual = qName;
}
 
public void characters(char[] c, int offset, int length) throws SAXException {
valorAtual = new String(c,offset,length).trim();
}
 
public void endElement(String arg0, String arg1, String arg2) throws SAXException {
Object value = portugueseData.get(tagAtual);
if(value != null)
data.put((String)value,valorAtual);
}
 
public Hashtable getData() {
return data;
}
 
}

Com esta classe, concluímos nosso estudo do código de consumo de web services e pudemos comprovar a facilidade de uso fornecida pela API, através da implementação de um parser XML padrão e da geração de código automatizada. Vamos agora compilar e rodar o nosso midlet.

Compilando e executando a aplicação

Para finalizar, vamos compilar, empacotar e executar a aplicação. Para tal, escolha a opção “Build -> Build Main Project” na barra de menu do NetBeans. Este procedimento compilará todas as classes e criará os pacotes .JAD e .JAR padrão para aplicações Java MicroEdition. </p>

A seguir, você poderá executar a aplicação dentro do emulador definido como o principal (S60 3rd. Edition MIDP SDK), bastando escolher as opções “Run ->; Main Project” no menu principal. O resultado será semelhante ao demonstrado nas Figuras 12 e 13:

Figura12 uws.jpg

Figura 12: Entrada de dados

Figura13 uws.jpg

Figura 13: Resultado da Consulta

Testando a aplicação em um telefone real

Você também pode testar sua aplicação em um dispositivo real. Por exemplo, se você possui um telefone da plataforma Nokia S60, como N73, N80, 6681, N90, etc., você pode transferir o arquivo “ClimaGlobal.jar”, encontrado no diretório “dist” do projeto do NetBeans para o telefone utilizando o “File Manager” da aplicação “PC Suíte” ou mesmo uma transferência direta via Bluetooth. O telefone reconhecerá o arquivo como uma aplicação instalável e o executará normalmente. Para um pequeno exemplo do procedimento, mostro abaixo o processo de instalação e execução da aplicação ClimaGlobal em meu Nokia E61i:

Screenshot0001.jpg Screenshot0002.jpg

Screenshot0003.jpg Screenshot0004.jpg

Screenshot0005.jpg Screenshot0006.jpg

Tabela 2: Execução da aplicação em um Nokia E61i

Conclusões

Embora criada facilmente, a aplicação desenvolvida neste artigo é bastante funcional e pode ser utilizada por diversos tipos de usuários, especialmente os que viajam bastante e precisam de notícias sobre o clima ao redor do mundo.

Os focos aqui não foram os gráficos ou a facilidade de uso, mas sim a utilização de uma nova API (JSR 172 – Web Services) e a demonstração de que ela se torna um facilitador ao desenvolvimento de aplicações distribuídas, pois ao nos fornecer um conjunto comum de interfaces e ser baseada em protocolos standard tais como XML, WSDL e SOAP, permite a construção de ferramentas que automatizam a geração de muito código que seria trabalhoso e tedioso escrever. Além disso, por ser um padrão da indústria, está sendo implementada em vários aparelhos (não só da Nokia mas como de outros fabricantes) o que aumenta o mercado-alvo das suas aplicações ao ampliar a base de usuários que podem utiliza-la sem modificações.


Version Hint

Windows Phone: [[Category:Windows Phone]]
[[Category:Windows Phone 7.5]]
[[Category:Windows Phone 8]]

Nokia Asha: [[Category:Nokia Asha]]
[[Category:Nokia Asha Platform 1.0]]

Series 40: [[Category:Series 40]]
[[Category:Series 40 1st Edition]] [[Category:Series 40 2nd Edition]]
[[Category:Series 40 3rd Edition (initial release)]] [[Category:Series 40 3rd Edition FP1]] [[Category:Series 40 3rd Edition FP2]]
[[Category:Series 40 5th Edition (initial release)]] [[Category:Series 40 5th Edition FP1]]
[[Category:Series 40 6th Edition (initial release)]] [[Category:Series 40 6th Edition FP1]] [[Category:Series 40 Developer Platform 1.0]] [[Category:Series 40 Developer Platform 1.1]] [[Category:Series 40 Developer Platform 2.0]]

Symbian: [[Category:Symbian]]
[[Category:S60 1st Edition]] [[Category:S60 2nd Edition (initial release)]] [[Category:S60 2nd Edition FP1]] [[Category:S60 2nd Edition FP2]] [[Category:S60 2nd Edition FP3]]
[[Category:S60 3rd Edition (initial release)]] [[Category:S60 3rd Edition FP1]] [[Category:S60 3rd Edition FP2]]
[[Category:S60 5th Edition]]
[[Category:Symbian^3]] [[Category:Symbian Anna]] [[Category:Nokia Belle]]

This page was last modified on 2 February 2014, at 14:55.
172 page views in the last 30 days.