Fazendo seus web services pegarem fogo com XFire

Um breve histórico sobre integração
Integrar aplicações sempre foi um dos grandes desafios no mundo da tecnologia da informação. A partir do momento em que passaram a existir duas aplicações autônomas em uma organização, a necessidade de integrá-las passou a existir. E, como a imaginação humana é algo surpreendente, surgiram diversas soluções para o problema da integração. No passado, algumas aplicações trocavam dados através de arquivos compartilhados. Nem é preciso dizer a tragédia que isso significa. Uma outra estratégia de integração foi fazer com que as duas aplicações trocassem informações diretamente através de sockets. Embora seja uma solução melhor do que a primeira, ainda não era muito efetiva. Controlar todo o processo de troca de mensagens através de socket necessitava ainda de duas coisas:

  1. um protocolo
  2. controle manual das transações

E isso tornava o trabalho de integração complicado. O passo seguinte foi dado através da criação de protocolos de RPC (remote procedure call), criando protocolos para a invocação de serviços públicos de outras aplicações e bases para manipulação de transações, mas ainda assim RPCs não resolviam o problema de integração, pois estes protocolos normalmente eram específicos para uma única plataforma (como Java RMI ou .NET Remoting), o que inviabilizava a integração entre sistemas feitos em plataformas distintas.

A próxima solução
A idéia dos mecanismos de RPC eram interessantes. Ao invés de se compartilhar dados (que poderiam ser facilmente corrompidos por diferentes sistemas, tornando-os inconsistentes), as aplicações passavam a compartilhar serviços especializados, disponibilizando uma série de regras de negócio a quem quisesse usar, mas sem que os dados ficassem indevidamente expostos. Porém, como dito anteriormente, tais mecanismos eram muitas vezes dependentes de uma determinada tecnologia, o que impossibilitava, por exemplo, que uma aplicação COBOL conversasse com uma aplicação Java.

Contudo, a idéia dos RPCs é boa e só precisava ser aprimorada. E, de certa forma, estes aprimoramentos vieram com os Web Services. De maneira bem resumida, pode-se considerar que os Web Services são mecanismos de RPC que utilizam padrões abertos (como o protocolo HTTP e o padrão XML) para troca de mensagens, permitindo, assim, que sistemas, mesmo de diferentes plataformas, possam interagir entre si. A plataforma Java suporta Web Services desde 2000, mas desde então produzir um Web Service em Java não tem sido uma tarefa muito simples (diferentemente dos nossos colegas programadores .NET, que são capazes de criar um simples Web Service em questão de minutos). Quer dizer, produzir um Web Service costumava não ser uma tarefa tão simples, pois este artigo vai lhe mostrar como é fácil criar um Web Service usando o XFire (http://xfire.codehaus.org), o novo framework para Web Services da Codehaus (www.codehaus.org).

Nota: Neste artigo, estamos supondo que você já tenha experiência na criação de aplicações Web. Para os exemplos deste artigo, foram usados Apache Tomcat 5.5 (http://tomcat.apache.org) como servlet container sobre JVM 1.5.0_06 (http://java.sun.com/j2se/1.5.0/) e XFire versão 1.1 (http://xfire.codehaus.org).

Code on fire!
Criar um WebService usando o XFire é tão simples quanto contar até 3:

  1. Crie uma classe Java com os serviços que você pretende disponibilizar (pode ser um Service Façade para vários outros componentes do seu sistema, isso não importa);
  2. Configure sua aplicação;
  3. Crie o cliente do seu Web Service;

Então, vamos contar até 3 e colocar nossos Web Services para funcionar.

Criando nossa classe Java
No nosso exemplo, vamos implementar um conversor de moedas. Na verdade, não é um conversor completo, é apenas um conversor de Reais (BRL) para Dólares (USD), Libras Esterlinas (GBL) ou Euro (EUR). O código segue conforme abaixo.

package org.nullability.xfire.demo.bank;
// interface para definição do nosso serviço
public interface CurrencyConversionService{
 public Double convert(Double ammount, String toCurrency);
}

package org.nullability.xfire.demo.bank.impl;
// implementação do nosso serviço de conversão de moedas
public class CurrencyConversionServiceImpl implements
                          CurrencyConversionService {
 public Double convert(Double ammount, String toCurrency){
      Double convertedAmmount = 0.0;
      if("BRL".equalsIgnoreCase(toCurrency)){
         convertedAmmount = ammount;
      } else {
         if("USD".equalsIgnoreCase(toCurrency)){
            convertedAmmount = ammount * 2.3;
         }
         if ("GBP".equalsIgnoreCase(toCurrency)){
             convertedAmmount = ammount * 4.21;
         }
         if ("EUR".equalsIgnoreCase(toCurrency)){
             convertedAmmount = ammount * 2.89;
         }
       } return convertedAmmount;
  }
}

Configurando nossa aplicação
A configuração se dá em 3 passos. O primeiro é configurar o servlet do XFire na nossa aplicação para que ele consiga disponibilizar nossas classes Java como Web Services. Para tanto, é preciso alterar o arquivo web.xml da sua aplicação web para que este servlet seja carregado.

XFire XFire Servlet org.codehaus.xfire.transport.http.XFireConfigurableServlet config services.xml XFire /servlet/XFireServlet/* XFire /services/*

O segundo passo é configurar quais serão os serviços a serem carregados e disponibilizados. Para isso, é preciso criar um arquivo chamado services.xml, onde definimos o nome do serviço, seu namespace e as classes que serão usadas neste serviço. Este arquivo deve ser colocado no class path da sua aplicação web, normalmente em WEB-INF/classes.

Banking bank org.nullability.xfire.demo.bank.CurrencyConversionService org.nullability.xfire.demo.bank.impl.CurrencyConversionServiceImpl

E, por fim, resolvemos as dependências do XFire, adicionando ao diretório WEB-INF/lib os seguintes arquivos .jar:

·         activation-1.0.2.jar

·         commons-codec-1.3.jar

·         commons-httpclient-3.0.jar

·         commons-logging-1.0.4.jar

·         jaxen-1.1-beta-8.jar

·         jdom-1.0.jar

·         log4j-1.2.x.jar

·         mail-1.3.3_01.jar

·         spring-1.2.x.jar

·         stax-api-1.0.jar

·         wsdl4j-1.5.2.jar

·         wstx-asl-2.9.jar

·         xbean-2.1.0.jar

·         xbean-spring-2.2.jar

·         xfire-all-1.0.jar

·         XmlSchema-1.0.jar

E estamos prontos. Para verificar se seu Web Service está funcionando, tente acessá-lo através da URL: http://localhost:8080/[NOME_DA_SUA_APLICACAO]/services/Banking?wsdl.

Criando o cliente
O cliente é bem simples. Ele apenas invoca o nosso serviço de conversão de moedas através da interface CurrencyConversionService que definimos (e isso explica o motivo pela qual criamos esta interface).

package org.nullability.xfire.demo.bank.client;

import java.net.MalformedURLException;
import org.codehaus.xfire.XFire;
import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.nullability.xfire.demo.bank.CurrencyConversionService;
import static java.lang.System.out;
 public class DummyClient {
 
     public static void main(String... args) throws MalformedURLException {
 
          Service serviceModel = new ObjectServiceFactory().create

                                         (CurrencyConversionService.class);
       // determina qual o tipo de objeto que vamos querer criar
 
          XFire xfire = XFireFactory.newInstance().getXFire();
       XFireProxyFactory factory = new XFireProxyFactory(xfire);
       // proxy para nosso serviço
       String serviceUrl = http://localhost:8080/XFire/services/Banking;

       // URL para acessar o web service
       CurrencyConversionService client = null;
       client = (CurrencyConversionService) factory.create(serviceModel,

                                                           serviceUrl);
       // obtendo referência ao proxy do seu web service.
      
Double ammount = client.convert(1000.0, "GBP");
       // invocando o serviço... out.println(ammount);
    }
}

Antes de executar o cliente do nosso Web Service, não se esqueça de configurar seu classpath com as dependências corretas:

·         commons-codec-1.3.jar

·         commons-logging-1.0.4.jar

·         commons-httpclient-3.0.jar

·         log4j-1.2.x.jar

·         servlet.jar

·         xfire-all-1.0.jar

·         XmlSchema-1.0.jar

Simples, fácil, rápido e indolor, como toda tecnologia deveria ser. XFire é um projeto muito promissor e que possui uma série muito grande de recursos a serem explorados, como compatibilidade com os mais importantes padrões Web Services (SOAP, WSDL, WS-I Basic Profile, WS-Addressing, WS-Security, WS-Attachments, etc), integração com Spring Framework, suporte a vários mecanismos de transporte (sim, você não precisa ficar preso ao protocolo HTTP se você não quiser!), além de oferecer suporte à JSR-181, que visa oferecer anotações para definições de Web Services. No entanto, este artigo é apenas um aperitivo. Temas mais complexos serão abordados mais para frente. Espero que tenham gostado e continuem acompanhando este humilde colunista. Até a próxima.