Android + AOP + kSOAP – Pt.4: Construindo Serviços Dinâmicos | ZBRA Soluções
Tags: Android, Annotations, AOP, KSOAP2, Web Services
Os últimos artigos da série Android+kSOAP, escritos por Bruno Silva, introduziram o conceito de integração entre aplicações android com web services, através de parses dinâmicos, cache e modularização/encapsulamento de elementos dentro de um conceito EAI (Enterprise Application Integration).
Este artigo tem como objetivo a criação dinâmica de serviços sem a implementação do mesmo. Estranho, não é? Não é estranho até adicionarmos o conceito AOP (Aspect Oriented Programming) à solução de integração.
Como o foco deste artigo não é AOP, fica como sugestão a leitura do artigo AOP com Spring.NET. Este artigo cobre o conceito de AOP, no qual estaremos mencionando nos próximos tópicos.
AOP é um conceito simples, porém com alguns níveis de implementação:
Linguagem de Programação: utilizar uma linguagem de programação que permite a construção de aspectos e acesso a recursos em tempo de execução e troca de mensagens entre os objetos em uma máquina virtual (por exemplo: Java Virtual Machine).
Proxy: utilizar o mecanismo de Proxy de uma linguagem de programação para criar objetos dinamicamente com atuação de um controle (handler) nas chamadas de métodos destes objetos.
O nível de implementação que vamos utilizar neste artigo é Proxy. Vamos utilizar a classe:
Construindo Web Service
Antes de começar a criação dos serviços do lado da aplicação android, vamos criar o web service que realizará os processamentos de nossas chamadas.
Vou criar um serviço simples, utilizando a tecnologia .NET WCF (Windows Communication Foundation):
public interface ISimpleService
string ProcessData(int value);
A implementação do serviço será:
public string ProcessData(int value)
return "Some Data!";
O serviço será publicado locamente para acesso da aplicação android.
Com o web service SimpleService publicado, vamos criar a solução para acesso aos seus dados, levando em consideração o conceito AOP.
A primeira parte será criar anotações para permitir o armazenamento de informações metadata do serviço que iremos acessar. Como assim? Criaremos uma anotação para o serviço e outra para as operações do serviço, respectivamente:
@Target (ElementType.TYPE )
public @interface SOAPService {
String serverUrl() default "";
String namespace() default "http://tempuri.org";
String serviceInterface() default "";
Vejam, que esta anotação permite as seguintes informações em nível de serviço:
serverURL: endereço do servidor que está publicado o web service.
namespace: nome do contexto que está publicado o serviço.
serviceName: nome do serviço publicado.
serviceInterface: nome da interface do serviço publicado.
public @interface SOAPServiceOperation {
Class parser();
String[] parameterNames() default {};
Já, esta anotação, permite informações em nível de operação de serviço:
name: nome da operação.
parser: implementação da interface IMethodResponseParser (veja o artigo Android+kSOAP – Pt.3).
parameterNames: conjunto de nomes que simboliza os paramêtros a serem enviados, como argumentos, na operação.
Com as anotações criadas, vamos criar a interface do serviço que acessará o web service:
@SOAPService(namespace="http://tempuri.org",
serverUrl="http://localhost:51827",
serviceInterface="ISimpleService",
serviceName="SimpleService")
@SOAPServiceOperation(name="GetData", parser=DummyServiceParser.class)
Pronto! Criamos uma interface que será utilizada para criar serviços, de forma dinâmica, baseados no WSDL do web service.
Notem, que a classe de conversão – DummyServiceParser – é uma implementação da interface, já conhecida, dos artigos anteriores, IMethodResponseParser.
public class DummyServiceParser implements IMethodResponseParser {
public Object parse(SoapObject soapObject, SoapMapper soapMapper) {
return soapMapper.parseSoapObjectIntoAnnotatedVO(DummyObject.class, soapObject);
Agora, precisamos construir o mecanismo para gerar serviços, via Proxy, incluindo um controle de chamadas para as invocações de metódos destes objetos. Este mecanismo será uma factory – ServiceFactory – que criará Proxy com o seguinte controle de chamadas – ServiceInvocationHandler.
public final class ServiceFactory {
private final <strong>ServiceInvocationHandler</strong> invocationHandler;
invocationHandler = new ServiceInvocationHandler();
public Object newService(Class<?> serviceInterfaceType) throws MalformedURLException {
if (!serviceInterfaceType.isInterface()) {
throw new IllegalArgumentException("Invalid type argument. Proxy service instance are created based on interface types.");
final ServiceInterfaceData serviceData = SoapAnnotationDataCache.addServiceInterface(serviceInterfaceType);
final URL url = serviceData.getServerUrl();
throw new MalformedURLException("Invalid server URL. Make sure that you set the [serverUrl] attribute from [" + SOAPService.class.getSimpleName() + "] annotation.");
return Proxy.newProxyInstance(ServiceFactory.class.getClassLoader(), new Class<?>[] { serviceInterfaceType }, this.invocationHandler);
Percebam, que a implementação do método ServiceFactory.newInstance utiliza a solução de cache do artigo Android+kSOAP – Pt.1. É anexado ao Proxy o controle de chamadas ServiceInvocationHandler.
public final class ServiceInvocationHandler implements InvocationHandler {
final ServiceInterfaceData serviceData = SoapAnnotationDataCache.getServiceInterfaceData(method);
final ServiceMethodData methodData = serviceData.getMethodData(method);
final String[] parameterNames = methodData.getParameterNames();
final LinkedHashMap<String, Object> params = new LinkedHashMap<String, Object>();
if (args != null && args.length != parameterNames.length) {
throw new IllegalArgumentException("The parameter names array length is different then invocation method arguments.");
if (args != null && parameterNames.length > 0) {
params.put(parameterNames[i], args[i]);
return new Caller<Object>()
.setServerUrl(serviceData.getServerUrl())
.setNamespace(serviceData.getNamespace())
.setService(serviceData.getServiceName())
.setServiceInterface(serviceData.getServiceInterface())
.setMethod(methodData.getName())
.setResponseParser(methodData.getParser()).call();
Mais uma vez, estou utilizando um elemento já conhecido, na série de artigos Android+kSOAP, o elemento Caller. Portanto, toda chamada realizada no Proxy, será direcionada ao controle de chamadas, que executará o acesso ao web service. O resultado da operação será convertido pela classe DummyServiceParser, anotada na operação do serviço.
Simplificar acesso a web service ou a recursos externos, utilizando conceitos de EAI, é primordial para evolução de softwares que necessitam deste tipo de solução.
Vejam, que no decorrer do artigo não mencionei sobre conversão e transformação automática dos dados enviados e retornados. Toda conversão é realizada por um parser, o que poderia ser um processo transparente para a utilização desta solução.
Uma solução open-source é a utilização da biblioteca ASoap. Esta biblioteca permite acesso de forma transparente, juntamente com a conversão e transformação de dados de um modo simples e flexível. Vale a pena dar uma olhada!
É isso aí pessoALL, fico por aqui!
Proxy com Android
Por GUSTAVO ROSSI MULLER em 1 de December de 2012 às 20:23
Gostei do seu artigo e dos artigos do Bruno, muito bons.
Você pode mostra um exemplo de como usar a biblioteca ASOAP para consumir o ws abaixo?
http://webservices.daehosting.com/services/eleventest.wso?op=IsAllNumbers
Por Fabio A. Falavinha em 14 de December de 2012 às 16:14
Oi Gustavo, segue um link para download de um exemplo:
https://docs.google.com/folder/d/0B3AIYF-EW9fjWFRibm1IU2dkTTA/edit
A partir do WSDL crie as classes que serão parte do parser do asoap, assim como no exemplo, você pode ver pela classe DummyObject.
Crie uma interface e anote-a usando as anotações do asoap, use o exemplo da classe DummyService.
Para realizar um teste de chamada ao serviço, veja no exemplo da classe ServiceTest, que ao chamar a classe ServiceFactory.newService(…), você terá um proxy em cima da sua interface para realizar as requisições.
Faça o código e poste aqui para que eu possa lhe ajudar.
Por gil em 27 de August de 2014 às 18:20
Olá boa noite não sei se nessa pastagem e o lugar certo. Mas preciso esclarecer essa dúvida com vocês. Estou desenvolvendo meu tcc que se trata de um sistema para gestão de academias e um app para alunos acessarem os treinos. Porém o prazo está muito curto pra criar o app nativo em Android li em alguns artigos que é possível criar um app Android que na verdade é apenas uma casca do app as funcionalidades estão todas no site por exemplo. Alguém poderia falar sobre isso ou indicar alguma referência.
Meu email: gil-real@hotmail.com
Por Fabio A. Falavinha em 27 de February de 2015 às 14:15
Peço desculpas por responder apenas agora.
Acesse o link abaixo para entender como o desenvolvimento nativo (específico para uma ou mais plataformas) ou cross-platform (mesmo código, porém distribuído para várias plataformas).