Caminhada ao Ego com Web Services

Rafael Steil

Aprenda como criar um WebService quase sem esforço algum, e de quebra mostre para seus amigos quem é famoso de fato



Caminhada ao Ego com WebServices


Bem vindo à edição de número 84 da The Java(tm) Specialists' Newsletter, e bem vindo ao ano 2004 D.C. Muitos anos atrás Cape Town tentou sediar as Olimpíadas, e isso era esperado para ocorrer esse ano. Infelizmente - ou talvez felizmente - Athenas ganhou o prêmio. Este ano estamos celebrando 10 anos de Democracia.

Janeiro de 2004 é um mês significante. É o primeiro mês desde Novembro 2001 que eu não publiquei uma newsletter. Agradeco todos os emails que recebi de vocês, incentivando-me a continuar. Por exemplo:

muito tempo sem newsletter :(


Eu apenas gostaria de lhe dizer que adorei ler a newsletter 82 em Alemão.


e este aqui:

Olá,
O que aconteceu, vc está muito ocupado?
Estou aguardando pela próxima.
;-)


Muito obrigado por estas pequenas notas, gostei bastate. Eu estive relativamente ocupado com um projeto que precisava ser terminado até 31 de Janeiro ( ou então, sem pagamento ), enquanto o resto do mundo esta celebrando, eu estava trabalhando em uma velocidade frenética.

Um de meus clientes pediu-me para investigar sobre como poderíamos usar WebServices e fornecer nossa própria maneira de transportar as mensagens XML, uma vez que o HTTP nao era apropriado para a aplicação.

Preciso admitir que sempre vi WebServices com ceticismo, compartilhado por várias outras pessoas. Quantos WebServices úteis iremos ver nos próximos anos, ou é tudo Silicon Snake Oil ( ótimo livro, por sinal )? Minhas frustações foram aumentadas nas tentativas de conseguir comunicação com WebServices REAIS. Acredite ou não, mas eu me esforço com novas tecnologias. Lembro-me quando os EJBs apareceram pela primeira vez, e o tempo que levou para eu fazer o primeiro deploy de um CMP.

A primeira implementação que olhamos foi a da Sun, o Java Web Services Developers Kit. A implementação jax-rpc funcionou a maior parte do tempo, porém perdi muito cabelo ( e tempo ) quando não funcionava.

De maneira alguma posso ser considerado especialista em WebServices. Minha experiência total é algo em torno de 2 semanas. Contudo, depois de ter começado a usar a implementação Axis, do Grupo Apache, fiquei excitado com as possibilidades de integração com sites mundialmente famosos através dos meus programas feitos em Java.

Um WebService Matemático
Antes de mais nada, irei lhe mostrar um WebService em Java com o qual você pode integrar:

01 public class Fibonacci 
02 {
03     public int calculate(int n
04     {
05         if (n < 0)
06             throw new IllegalArgumentException("number must be >= 0");
07         switch (n
08         {
09             case 0:
10                 return 0;
11             case 1:
12                 return 1;
13             default:
14                 return calculate(n - 2+ calculate(n - 1);
15         }
16     }
17 }


A calculadora Fibonacci é um excercício muito bom que uso para quebrar o espírito extremamente confiante dos estudantes de Java. Falando em estudantes, eis aqui uma pequena pausa para um comercial: Seja treinado por progradores experientes. Venha para Maximum Solutions e aprenda como escrever excelente, eficiente, bom código em Java. Entre em contato com nós simplesmente enviando um email. A razão pela qual este código causa problemas é a sua natureza recursiva. Mesmo fibonacci(100) irá levar um tempo enorme para executar.

Como convertemos esta classe Java para um WebService? Compilamos? Adicionamos uma interface e escrevemos um documento WSDL ( Web Services Description Language )?

Não, é muito mais fácil. Comece pegando o Apache Axis versão 1.1. Instale o Axis e o Tomcat. Em seguida, copie o diretório "axis", que esta localizado em "webapps", de dentro do diretório de instalação do Axis, e copie para o diretório de aplicações do Tomcat, geralmente "webapps". Inicie o Tomcat. O Axis deverá estar rodando. Acesse http://localhost:8080/axis e valide a sua instalação. Se não funcionar, dê uma olhada na documentação de instalação que vem com o Axis.

Agora vem a parte legal. Pegue o arquivo "Fibonacci.java" ( não o .class ), copie ele para o diretório webapps/axis e renomeie o arquivo para Fibonacci.jws. Parabéns. Você acabou de escrever o seu primeiro WebService. É incrivelmente simples. Você pode verificar o funcionamento acessando http://localhost:8080/axis/Fibonacci.jws. A página padrão lhe mostra um link para o arquivo WSDL descrevendo a interface para a classe em uma linguagem que todo mundo pode entender ( exceto humanos ).

Acessando o WebService

O cliente para o WebService eh um pouco mais dificil ( uma versão mais simples vem em seguinda ).

01 public class FibClient 
02 {
03     public static void main(String[] argsthrows Exception 
04     {
05         String endpoint = "http://localhost:8080/axis/Fibonacci.jws";
06         Service service = new Service();
07         Call call = (Callservice.createCall();
08         call.setTargetEndpointAddress(endpoint);
09         call.setOperationName("calculate");
10         Integer ret = (Integercall.invoke(new Object[]{new Integer(args[0])});
11         System.out.println("Got result : " + ret);
12     }
13 }


Voce deverá ter o CLASSPATH configurado corretamente. Eu assumo que os leitores regulares da newsletter irão saber da propriedade do sistema java.ext.dirs, a qual você pode usar para apontar para um diretório ou arquivo JAR, ao invés de colocar todos eles no seu CLASSPATH. For exemplo, vamos considerar que o Axis foi instalado em c:\java\axis-1_1, e as classes compiladas estão no diretório "classes". Uma vez que tenhamos compilado o programa FibClient, podemos rodá-lo usando:

java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 0
Got result : 0
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 1
Got result : 1
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 2
Got result : 1
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 3
Got result : 2
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 4
Got result : 3
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 5
Got result : 5
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 6
Got result : 8
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes FibClient 30
Got result : 832040


Tornando o código mais simples
A IBM é uma grana companhia. Eles escrevem excelente código open source, free software, os quais podemos usar para produzir bom software. Uma de suas fantásticas ferramentas é o WSDL2Java. Você pode invocá-lo no WebService que acamos de escrever:

java -Djava.ext.dirs=c:\java\axis-1_1\lib org.apache.axis.wsdl.WSDL2Java
http://localhost:8080/axis/Fibonacci.jws?wsdl -o src -p com.maxoft.fib.clien

Isso gera alguns arquivos que podemos usar para tornar nosso cliente mais simples de escrever. O pacote onde os arquivos ficam esta em com.maxsoft.fib.clint, portanto é para lá que irei adicionar a nova classe FibClient:

01 package com.maxoft.fib.client;
02 
03 public class FibClient2 {
04     public static void main(String[] argsthrows Exception {
05         FibonacciService service = new FibonacciServiceLocator();
06         Fibonacci fib = service.getFibonacci();
07         
08         for (int i=0; i<10; i++) {
09             System.out.println("fib(" + i + ")=" + fib.calculate(i));
10         }
11     }
12 }


E isso é tudo o que você precisa fazer. Rode o código com o seguinte comando:

java -Djava.ext.dirs=lib -classpath classes com.maxoft.fib.client.FibClient2

fib(0)=0
fib(1)=1
fib(2)=1
fib(3)=2
fib(4)=3
fib(5)=5
fib(6)=8
fib(7)=13
fib(8)=21
fib(9)=34





E agora, a Caminhada ao Ego
Fama é quando você caminha em uma sala e lá há mais gente que conhece você do que você conhece. Meu sogro foi o melhor jogador de futebol na África do Sul nos seus dias de glória. E, 20 anos depois, pessoas encontram com ele na rua e dizem: "Lembra de 1968, quando comemoramos a sua vitória juntos?". Claro que ele não se recorda, mas ele também nao deseja desapontar seus fans.

A questão é: o quão famoso é você? dependendo do seu nome, isso pode ser uma coisa difícil de determinar. Meu nome é fácil. Sou o único "Heinz Kabutz" vivo no planeta. Meu amigo John Green provavelmente tem outro John Green vivendo na mesma rua. Portanto, os resultados de uma busca no Google não devem ser levados tão a sério.

O Google publicou uma interface para um WebService que podemos usar para realizar buscas. O WSDL esta disponível em http://api.google.com/GoogleSearch.wsdl. O Google torna este arquivo disponível para o público em geral, portanto há algumas restrições de uso. Por exemplo, você deve se registrar no site para obter uma licensa de uso, a qual você envia a cada requisição. Há também um limite de 1000 requisições por dia, assim como algumas outras restrições. Leia atentamente a documentação no site do Google. Eu gostaria de continuar EgoSurfando no Google através do meu programa, portanto, por favor, não abuse da boa vontade deles ;-)

Em adição ao WSDL, o Google disponibiliza uma API em forma de Facade para o Java. Porém, uma vez que eu estava tenztando aprender em como interagir com um WebService, usei o Axis para conversar com o Google. Foi extremamente mais simples que eu pensava que seria. Em primeiro lugar, é uma boa idéia gerar as classes Java a partir do WSDL:

java -Djava.ext.dirs=c:\java\axis-1_1\lib org.apache.axis.wsdl.WSDL2Java
http://api.google.com/GoogleSearch.wsdl -o src

Isso cria os seguintes arquivos no package GogleSearch:

DirectoryCategory.java
GoogleSearchBindingStub.java
GoogleSearchPort.java
GoogleSearchResult.java
GoogleSearchService.java
GoogleSearchServiceLocator.java
ResultElement.java


O próximo passo é programar o client. Estou usando as classes geradas para realizar uma pesquisa por nomes famosos:

01 package com.maxoft.webservices;
02 
03 import GoogleSearch.*;
04 
05 import javax.xml.rpc.ServiceException;
06 import java.rmi.RemoteException;
07 import java.util.*;
08 
09 public class EgoTrip {
10     private final GoogleSearchPort port;
11     private final String googleKey;
12 
13     public EgoTrip(String googleKeythrows ServiceException {
14         this.googleKey = googleKey;
15         GoogleSearchService service = new GoogleSearchServiceLocator();
16         port = service.getGoogleSearchPort();
17     }
18 
19     private int measureFame(String namethrows RemoteException {
20         GoogleSearchResult result = port.doGoogleSearch(
21             googleKey, name, 010, false, "", false, """UTF-8""UTF-8");
22         return result.getEstimatedTotalResultsCount();
23     }
24 
25     public static void main(String[] argsthrows Exception {
26         String[] famousPeople = {
27             "Bruce Eckel"// famous Java author
28             "John Vlissides"// famous Design Pattern author
29             "Cay Horstmann"// famous Java author
30             "Erich Gamma"// famous Design Pattern author
31             "Martin Fowler"// famous author
32             "Jörn Schmidt-Dumont"// my sales manager
33             "Heinz Kabutz"// me
34             "Pieter Kritzinger"// my prof at university
35             "Helene Kabutz"// my wife
36             "Marten Kabutz"// my older brother
37             "Rudolf Kabutz"// my oldest brother
38             "Bettina Kabutz"// my sister
39             "Bjarne Stroustrup"// famous C++ inventor
40             "Mark Shuttleworth"// famous Thawte founder
41             "Bill Gates"// apparently wrote some software
42             "Costa Kytides"// #14 in the world street-luger
43             "Anesti Kytides"// stand-up skate-boarder
44             "John Green"// friend from university
45         };
46         Set people = new TreeSet();
47 
48         EgoTrip et = new EgoTrip(args[0]);
49         for (int i = 0; i < famousPeople.length; i++) {
50             System.out.println("Egotripping " + famousPeople[i]);
51             int fame = et.measureFame(famousPeople[i]);
52             people.add(new Person(fame, famousPeople[i]));
53         }
54 
55         System.out.println();
56         System.out.println("Hall of Snake Oil Fame");
57         
58         for (Iterator it = people.iterator(); it.hasNext();) {
59             System.out.println(it.next());
60         }
61     }
62 
63     private static class Person implements Comparable {
64         private final int fame;
65         private final String name;
66 
67         public Person(int fame, String name) {
68             this.fame = fame;
69             this.name = name;
70         }
71 
72         public int compareTo(Object o) {
73             Person other = (Persono;
74             int result = other.fame - fame;
75             if (result == 0) {
76                 return name.compareTo(other.name);
77             }
78             return result;
79         }
80 
81         public String toString() {
82             return name + " (" + fame + ")";
83         }
84     }
85 }


Quando você roda esse programa, é necessário informar a sua licensa de uso fornecida pelo Google, que você recebe quando se registra. O registro voce pode fazer em http://www.google.com/apis. O programa você roda com a seguinte linha de comando:

java -Djava.ext.dirs=lib -classpath classes com.maxoft.webservices.EgoTrip YOUR_GOOGLE_LICENSE_KEY

Quando você rodar este programa, a newsletter já estará no site, e quem sabe o Google já tenha indexado isso também? Caso positivo, os números podem ser diferentes. De fato, eles provavelmente serão diferentes por causa que são apenas estimados. Desculpe Bill Gates, você não está no topo, meu amigo John Green é mais famoso:

Egotripping Bruce Eckel
Egotripping John Vlissides
Egotripping Cay Horstmann
Egotripping Erich Gamma
Egotripping Martin Fowler
Egotripping Jörn Schmidt-Dumont
Egotripping Heinz Kabutz
Egotripping Pieter Kritzinger
Egotripping Helene Kabutz
Egotripping Marten Kabutz
Egotripping Rudolf Kabutz
Egotripping Bettina Kabutz
Egotripping Bjarne Stroustrup
Egotripping Mark Shuttleworth
Egotripping Bill Gates
Egotripping Costa Kytides
Egotripping Anesti Kytides
Egotripping John Green

Hall of Snake Oil Fame
John Green (3360000)
Bill Gates (1630000)
Martin Fowler (207000)
Bruce Eckel (29300)
Bjarne Stroustrup (22900)
Erich Gamma (21600)
Mark Shuttleworth (16000)
John Vlissides (14000)
Cay Horstmann (7880)
Heinz Kabutz (874)
Pieter Kritzinger (846)
Rudolf Kabutz (36)
Jörn Schmidt-Dumont (35)
Anesti Kytides (18)
Costa Kytides (16)
Helene Kabutz (11)
Bettina Kabutz (9)
Marten Kabutz (6)


Ao menos eu apareço mais freqüentemente que meu professor da Universidade de Cape Town ;-)

Obrigado por ler esta newsletter,

Atenciosamente,
Heinz

Sobre a The Java Specialists Newsletter

Este artigo é fruto de uma parceria entre o GUJ e o autor da The Java Specialists Newsletter, Dr. Heinz M. Kabutz. Originalmente publicadas em inglês e enviadas para milhares de leitores ao redor do planeta, o GUJ propô-se a realizar a tradução para o Português do conteúdo, disponibilizando assim um ótimo material para um número ainda maior de leitores.

Você encontra o documento original, assim como newsletters anteriores, no site oficial, em http://www.javaspecialists.co.za


Copyright © 2002-2006 GUJ | Todas as marcas e marcas registradas que aparecem no GUJ são de propriedade de seus respectivos donos