Vous êtes sur la page 1sur 8

Como distribuir servicos Web usando o Axis

Davi da Silva Boger


20 de junho de 2006
Resumo
Este artigo traz uma introduc ao de como distribuir servicos Web im-
plementados em Java no Apache Axis. O Apache Axis traz ferramentas
que auxiliam no processo da implementa c ao e disponibilizac ao do servico.
O presente documento explica tanto como disponibilizar um servico ma-
nualmente, como usando as ferramentas disponveis.
1 Introducao
O Apache Axis e uma ferramenta que auxilia tanto o desenvolvimento como a
disponibilizacao de Servicos Web. Existem implementa coes para as linguagens
C++ e Java. Aqui sera abordada apenas a implementa cao para Java. Na etapa
de criacao do servico, o Axis dispoe de uma ferramenta para gerar um arquivo
WSDL a partir de uma interface Java (Java2WSDL), e uma ferramenta para
geracao de codigo a partir de um arquivo WSDL (WSDL2Java).
Para a etapa de disponibilizacao do servico, o Axis traz uma aplicacao Web
(que pode ser usada em qualquer Web Containter, como o Tomcat) que, por sua
vez, e um container para servicos Web. Toda o esforco de serializacao e deseria-
lizacao das mensagens, invocacao dos metodos, e tratada automaticamente pela
aplicacao. Alem disso, a engine Axis usa o conceito de interceptadores (han-
dlers). Os handlers podem ser denidos para interceptar as mensagens SOAP
nos pontos de entrada e sada, na aplicacao cliente e no servidor. Este acesso
`as mensagens permite que varias caractersticas sejam implementadas de forma
transparente ao servico.
Ha duas formas de distribuir servicos no Axis: a distribuicao instantanea
e a distribuicao personalizada. A distribuicao instantanea a rapida e simples,
porem nao permite que o usuario altere nenhuma opcao da distribuicao. Para
isso deve-se usar a distribuicao personalizada. Nesta ultima, o usuario modica
as opcoes de distribuicao atraves de um arquivo de descricao de distribuicao
de servico Web (Web Service Depolyment Descriptor - WSDD). Ao longo do
artigo, um servico exemplo sera implementado, distribudo e testado usando as
funcionalidades da ferramenta Axis.
2 Distribuicao instantanea

E a forma mais simples de distribuir servicos Web no Axis. Para realizar a


distribuicao instantanea, basta copiar o arquivo fonte da classe Java que imple-
menta o servico para o diretorio raiz da aplicacao do Axis, trocando a extensao
1
package exemplo;
public class ServicoExemplo {
public int dobro(int x) {
return 2 * x;
}
public int triplo(int x) {
return 3 * x;
}
public int quadruplo(int x) {
return 4 * x;
}
}
Figura 1: Codigo fonte da classe Java de exemplo
do arquivo de .java para .jws. E pronto. Basta iniciar o servidor de aplicacao
e o servico ja estara disponvel.
Para ilustrar, suponha que se quer distribuir um servico que calcule o dobro,
o triplo ou o quadruplo de um n umero. O codigo fonte da classe Java que
implementa o servico esta listado na gura 1. Apos escrever o fonte, basta
salvar o arquivo, com extensao .jws, no diretorio raiz da aplicacao do Axis
($CATALINA_HOME/webapps/axis/, no Tomcat, onde a variavel CATALINA_HOME
e o diretorio raiz do Tomcat), como descrito. A partir deste momento, tudo
e feito pelo Axis: O arquivo fonte e localizado, compilado, o arquivo WSDL e
gerado, e as mensagens SOAP sao devidamente transformadas em invocacoes
dos metodos da classe implementada. Todos os metodos p ublicos da classe sao
adicionados `a interface do servico.
Para testar o servico, abra um browser e digite o seguinte endereco:
http://localhost:8080/axis/ServicoExemplo.jws. Deve aparecer a men-
sagem There is a Web Service here, e um link para o WSDL do servico.
Clique no link para ver o arquivo de descricao do servico (WSDL) que e gerado
automaticamente pelo axis por meio da classe.
Uma forma de testar a chamada dos metodos da classe distribuda e passando
variaveis para a chamada na barra de enderecos do browser. Se, alem da URL do
servico, for digitado ?method=dobro, signica que o metodo dobro() da classe
sera invocado. Podem ser necessaria, ainda, outras variaveis, que representam
os argumentos da chamada, caso ela use algum. No exemplo, e necessario dizer
o n umero do qual se deseja calcular o dobro. Para isso, pode-se acrescentar o
texto &param=N, onde N e o n umero passado como parametro. Como resposta
para essa chamada, deve aparecer no browser a mensagem SOAP retornada pelo
servico. Outra forma de testar uma chamada de metodo de um servico e por
meio de um programa cliente. Essa forma sere descrita na secao 4.
Apesar de simples e rapida, a distribuicao instantanea nao permite nenhuma
2
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="ServicoExemplo" provider="java:RPC">
<parameter name="className"
value="exemplo.ServicoExemplo"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Aplication"/>
</service>
</deployment>
Figura 2: Arquivo WSDD distribuindo o servico exemplo.
conguracao na forma como distribumos o servico. Nao podemos, por exem-
plo, especicar quais metodos da classe serao distribudos, adicionar handlers,
entre outros. Para congurar essas opcoes, e necessario fazer a distribuicao
personalizada.
3 Distribuicao personalizada

E atraves desta forma de distribuicao que todas funcionalidades do Axis podem


ser exploradas. Para realizar a distribuicao personalizada utiliza-se um arquivo
WSDD. Um arquivo WSDD descreve como um servico (ou um handler) deve ser
disponibilizado. Varios parametros podem ser especicados em um arquivo de
descricao, am de personalizar a distribuicao do servico.

E no WSDD tambem,
que se pode denir quais handlers devem interceptar as mensagens de entrada e
sada do servico. Para o servico exemplo, um arquivo de descricao simples esta
listado na gura 2.
O elemento <deployment> informa para o Axis que se trata de um ar-
quivo WSDD, e os lhos deste elemento devem ser adicionados `a aplicacao.
O elemento <service> indica que se deseja distribuir um servico Web. O
parametro name deste elemento corresponde ao nome do servico que se esta
distribuindo, e o parametro provider indica que o servico segue as convencoes
SOAP-RPC para invocar os metodos da classe. Os elementos <parameter>
especicam as conguracoes da distribuicao do servico. Para o exemplo, a
classe (exemplo.ServicoExemplo) e os metodos acessveis (* signica todos
os metodos p ublicos da classe).
Com o arquivo WSDD em maos, pode-se distribuir o servico. Para isso, deve-
se executar o AdminClient, que vem com o Axis, passando o arquivo WSDD
como parametro. Antes, porem, e necessario colocar as classes compiladas em
um local onde o Axis possa encontra-las, no diretorio WEB-INF/classes, dentro
da aplicacao do Axis. Esse e o diretorio raiz de onde as denicoes de classe dos
servicos sao carregadas pelo Axis para poderem ser instanciadas (tambem pode-
se empacotar as classes do servico em um arquivo .jar, ou similar, como .war,
e colocar na pasta WEB-INF/lib). Assim, o parametro className tem como
diretorio base WEB-INF/classes. Para rodar o AdminClient deve-se executar
a classe org.apache.axis.client.AdminClient, passsando como parametro o
arquivo WSDD:
> java org.apache.axis.client.AdminClient deploy.wsdd
3
<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
<service name="ServicoExemplo"/>
</undeployment>
Figura 3: Arquivo WSDD para remover o servico exemplo do Axis.
package exemplo;
public interface ServicoExemplo extends java.rmi.Remote {
public int dobro(int x) throws java.rmi.RemoteException;
public int triplo(int x) throws java.rmi.RemoteException;
public int quadruplo(int x) throws java.rmi.RemoteException;
}
Figura 4: Interface para automatizar a distribuicao personalizada
(supondo que o arquivo de descricao seja mesmo deploy.wsdd, e que as biblio-
tecas do Axis estejam no classpath).
Para remover um servico do Axis, basta executar o AdminClient passando
um arquivo WSDD, onde a tag externa e <undepolyment>, como na gura 3.
Este elemento indica que seus lhos devem ser retirados a aplicacao do Axis.
Na distribuicao descrita acima, o servico exemplo e disponibilizado justa-
mente como na distribuicao instantanea. No entanto, para servicos mais com-
plexos, sera necessario especicar mais caractersticas no arquivo WSDD e es-
creve-lo manualmente se torna uma tarefa difcil e cansativa. Existem, para
isso, ferramentas no Axis que automatizam todo o processo. Essas ferramentas
sao Java2WSDL e WSDL2Java.
Java2WSDL gera um arquivo WSDL a partir de uma interface java.
WSDL2Java gera o arquivo WSDD, e o codigo basico para a implementa cao do
servico e do cliente. Para automatizar todo o processo de distribuicao persona-
lizada, devemos prosseguir da seguinte forma:
1. Escrever e compilar uma interface com os metodos que devem estar
acessveis no servico. A interface deve extender java.rmi.Remote e todos os
metodos devem lancar a excecao java.rmi.RemoteException. Para o servico
exemplo, a interface ca como na gura 4.
2. Executar o Java2WSDL para gerar um arquivo WSDL a partir da inter-
face.
> java org.apache.axis.wsdl.Java2WSDL -o ServicoExemplo.wsdl
-l"http://localhost:8080/axis/services/ServicoExemplo"
-n "urn:ServicoExemplo" -p"exemplo" "urn:ServicoExemplo"
exemplo.ServicoExemplo
onde:
-o indica o nome do arquivo WSDL gerado;
-l indica a localizacao (URL) do servico;
-n indica o namespace do WSDL gerado;
4
-p indica um mapeamento do pacote Java para o namespace;
a classe passada como parametro e a interface do servico, mostrada na
gura 4.
3. Executar o WSDL2Java para gerar o arquivo WSDD, o stub e outras
classes para facilitar a criacao do servico e do programa cliente.
> java org.apache.axis.wsdl.WSDL2Java -o
-d Application -s -S true
-N "urn:ServicoExemplo" "exemplo"
ServicoExemplo.wsdl
onde:
-o indica o diretorio onde os arquivos gerados serao colocados;
-d indica o escopo do servico;
-s indica que se quer gerar as classes do lado do servidor;
-S indica que se quer gerar o skeleton para o servico;
-N indica um mapeamento do namespace do servico para o pacote Java;
o arquivo WSDL especicado e o mesmo gerado no passo 2.
Para o comando acima, serao gerados os seguintes arquivos:
deploy.wsdd - arquivo de descricao de distribuicao para distribuir o ser-
vico;
undeploy.wsdd - arquivo de descricao de distribuicao para remover o
servico;
ServicoExemploSoapBindingImpl.java - classe que implementa o servi-
co;
ServicoExemploSoapBindingSkeleton.java - skeleton do servico, im-
plementa a interface do servico;
ServicoExemplo.java - interface do servico;
ServicoExemploSoapBindingStub.java - stub do cliente, implementa a
interface do servico;
ServicoExemploService.java - interface que representa o servico;
ServicoExemploServiceLocator.java - classe responsavel por prover
instancias de stubs, usada pela aplicacao cliente.
4. implementar a classe *SoapBindingImpl.java (
ServicoExemploSoapBindingImpl.java no exemplo) com o codigo do servico.
5. compilar as classes geradas no passo 3 e separar as classes do servico
(*SoapBindingSkeleton e *SoapBindingImpl) das classes do cliente.
5
6. Juntar as outras classes do servico (caso haja alguma) com as classes
geradas automaticamente que nao fazem parte do cliente.
7. Por ultimo, deve-se mover as classes do servico para o diretorio
WEB-INF/classes e executar o AdminClient passando o arquivo WSDD gerado
no passo 3.
Para servicos onde dados de tipos complexos sao enviados nas mensagens
SOAP, o passo 3 acima gerara classes serializaveis que representam esses tipos.
Essas classes implementam XML beans que o Axis usa para enviar objetos
estruturados nas mensagens SOAP. Essas classes de objetos serializaveis sao
geradas a partir de denicoes Schema presentes no WSDL do servico. No lado
do servico, os mapeamentos de tipos sao denidos no arquivo WSDD. No lado
do cliente, os mapeamentos sao denidos na classe stub.
Vale a pena mencionar que os passos acima podem ser executados por um
script. O Axis traz, para isso, denicoes de tarefas Ant. Na documentacao do
Axis ha um tutorial que ensina a usar essas tasks.
4 Criando um programa cliente
Se for feita a distribuicao instantanea, ou nao forem usadas as ferramentas
Java2WSDL e WSDL2Java, dever-se-a escrever um cliente manualmente. Um
cliente deve instanciar a classe org.apache.axis.client.Service e, a par-
tir dessa instancia, invocar o metodo createCall(), que instancia um objeto
do tipo org.apache.axis.client.Call. Deve-se entao invocar os metodos
setTargetEndpointAddress() passando a URL do servico como parametro, e
depois setOperationName passando um objeto javax.xml.namespace.QName
representando o nome da operacao. Depois disso, basta chamar o metodo
invoke(), passando um array do tipo java.lang.Object[], contendo os pa-
rametros para a chamada remota. Para o servico exemplo, um cliente simples
que invoca o metodo dobro passando 12345 e mostra o resultado, esta listado
na gura 5.
Caso sejam usadas as ferramentas Java2WSDL e WSDL2Java, basta usar a
classe *ServiceLocator e invocar o metodo get*(), onde * e o nome do servico.
Este metodo retornara um stub para o servico, que implementa a interface do
servico e cuida da invocacao remota dos metodos. Assim nao e necessario se
preocupar com os detalhes da chamada. Para o servico exemplo, um cliente que
usa as classes geradas automaticamente esta listado na gura 6.
6
public class Client {
public static void main(String[] args) {
try {
String endPoint =
"http://localhost:8080/axis/services/ServicoExemplo";
org.apache.axis.client.Service service =
new org.apache.axis.client.Service();
org.apache.axis.client.Call call;
call = (org.apache.axis.client.Call)
service.createCall();
call.setTargetEndpointAddress(endPoint);
call.setOperationName(
new javax.xml.namespace.QName("dobro"));
System.out.println(
call.invoke(new Object[] { 12345 }));
} catch (javax.xml.rpc.ServiceException e) {
e.printStackTrace();
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
}
}
Figura 5: Cliente para o ServicoExemplo que imprime na tela o dobro de 12345
7
public class Client {
public static void main(String[] args) {
try {
ServicoExemploServiceLocator locator =
new ServicoExemploServiceLocator();
ServicoExemplo servico = locator.getServicoExemplo();
System.out.println(servico.dobro(12345));
} catch (javax.xml.rpc.ServiceException e) {
e.printStackTrace();
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
}
}
Figura 6: Cliente para o ServicoExemplo que imprime na tela o dobro de 12345,
usando as classes geradas pela ferramente WSDL2Java
8