Web Services
Um serviço é uma funcionalidade de um sistema informático que pode ser invocada remotamente através da rede,
usando protocolos de comunicação da World Wide Web, nomeadamente, HTTP.
A tecnologia permite também a utilização de outros transportes.
WSDL
Os Web Services têm uma linguagem própria para descrever o seu contrato com os clientes.
A WSDL permite especificar a interface funcional, chamada port type, que define as
operações com entradas, saídas e erros.
A WSDL define também a interface concreta, com escolhas de tecnologias concretas a usar.
Cada escolha é representada num binding.
Exemplo de um contrato WSDL:
- Ping.wsdl -
o documento contém comentários numerados que explicam as diferentes secções do documento:
namespaces,
service definition,
binding definitions,
port type definitions,
message definitions e
type definitions.
Web Services em Java
A plataforma Java inclui uma implementação dos Web Services.
A biblioteca chama-se JAX-WS, que significa Java API for XML Web Services.
É possível implementar Web Services partindo de um contrato WSDL existente.
Esta abordagem ao desenvolvimento de serviços é chamada contract-first.
A ferramenta wsimport permite gerar código a partir do contrato WSDL,
para clientes e para servidores.
A JAX-WS também permite intercetar as mensagens SOAP que são enviadas ou recebidas pelo serviço,
através de objetos chamados handlers.
Exemplo Ping Web Service:
Nota: as pastas que contêm o código não devem ter espaços nem caracteres acentuados no seu caminho.
JUnit Integration Tests (IT)
Os testes de integração de Web Services permitem verificar
se o contrato das operações remotas definidas no WSDL está a ser respeitado por um servidor.
Os IT são definidos no cliente (ws-cli) e fazem invocações remotas ao servidor (ws).
Assume-se que todos os servidores foram lançados antes de correr os testes de integração.
Informação adicional sobre Web Services
-
Livro Couloris, Capítulo 9
-
Apresentação das normas principais
-
Apresentação da implementação
Exercício
O ponto de partida do exercício é um Web Service de um fornecedor de produtos e um cliente para o mesmo.
O código fornecido inclui um servidor incompleto
(supplier-ws
) e
um cliente incompleto
(supplier-ws-cli
).
-
As classes de domínio da aplicação já estão implementadas.
-
Consulte o pacote domain do servidor.
-
Identifique o Domain Root e
as restantes entidades representadas nas classes.
-
Analise os mecanismos de sincronização que são utilizados para garantir que as classes podem ser chamadas corretamente por múltiplas tarefas (threads).
-
De seguida,
consultar o contrato WSDL do serviço a implementar:
- Supplier WSDL
-
Analise o contrato para ver que operações define e
quais os respectivos parâmetros e exceções.
-
Vamos gerar código Java a partir do WSDL.
O Maven está configurado para chamar a ferramenta wsimport.
-
Copie o ficheiro WSDL do serviço a implementar para a pasta src/main/resources do servidor.
-
Vamos agora gerar o código Java do servidor a partir do WSDL:
cd supplier-ws
-
mvn generate-sources
Caso o WSDL esteja bem formado e válido,
a ferramenta wsimport gera vários ficheiros que suportam o web service.
Entre eles, estarão as classes para os tipos complexos usados como parâmetros
e a interface Java que define o Web Service.
-
Faça refresh no Eclipse e
consulte as classes geradas na pasta:
target/generated-sources/wsimport.
Em especial,
consulte a classe ...Service, e
descubra a interface Java ...PortType que foi gerada a partir do WSDL.
-
Vamos agora concretizar o serviço.
-
Consulte a classe de implementação do serviço ...PortImpl,
que deverá implementar a interface Java gerada.
-
Deverá associar a classe PortImpl ao WSDL através da
anotação @WebService com os seguintes atributos:
endpoint interface (nome do tipo Java do PortType),
wsdlLocation (nome do ficheiro WSDL),
name (definido no WSDL),
portName (WSDL),
targetNamespace (WSDL) e
serviceName (WSDL).
-
Além da anotação, todos os métodos listados na interface PortType
devem ser implementados na classe do serviço.
Cada método é uma operação do Web Service,
com entradas, saídas e excepções.
Para cada operação, confira se está corretamente implementada.
Adicione a anotação @Override antes de cada método de operação,
para que o compilador confirme que está a implementar corretamente
o método definido na interface.
Note que as operações searchProducts e buyProducts
não estão implementadas.
Para já vamos compilar e executar o servidor sem estas operações estarem concluídas.
-
Executar o servidor:
-
mvn compile exec:java
O nome da classe a executar e
os argumentos estão definidos no pom.xml
O servidor deve executar sem erros,
disponibilizando o endpoint address.
-
Confirmar que o servidor está à espera de pedidos no endereço:
Vamos agora usar o cliente supplier-ws-cli para testar o servidor.
-
Vamos gerar o código Java para invocação do serviço.
-
Consultar o pom.xml do cliente para confirmar que o WSDL está a ser corretamente referenciado
(propriedades wsdl.directory e wsdl.filename)
-
cd supplier-ws-cli
-
mvn generate-sources
As classes são geradas na pasta:
target/generated-sources/wsimport.
-
Vamos fazer uma chamada simples, correndo a aplicação cliente.
-
mvn compile exec:java
A operação auxiliar ping deverá ser invocada.
-
Depois deste teste pontual, vamos correr os testes de integração já existentes.
-
mvn verify
O Maven executa todos os testes contidos em classes ...IT e
apresenta um resumo dos resultados obtidos.
Se tudo correr bem, os testes passaram todos.
Vamos agora analisar, em detalhe, as mensagens SOAP usadas para comunicação entre cliente e servidor.
Vamos ativar um handler no servidor (classe PrintSOAPHandler) que vai intercetar e imprimir as mensagens SOAP para a consola.
-
Na pasta src/main/resources
já se encontra um ficheiro supplier-ws_handler-chain.xml com a configuração da cadeia de interceção.
-
Para ativarmos o handler, temos que adicionar a seguinte anotação ao PortImpl:
@HandlerChain(file = "/supplier-ws_handler-chain.xml")
-
Recompilar e relançar o servidor.
- cd supplier-ws
- mvn compile exec:java
-
Usar o cliente para chamar o ping.
- cd supplier-ws-cli
- mvn compile exec:java
-
Agora, ao receber mensagens, estas serão capturadas e
impressas para a consola do servidor.
-
Qual é a etiqueta principal da mensagem SOAP?
-
Onde são transportados os argumentos das operações? E os resultados?
O que falta fazer?
-
No servidor:
-
Implementar searchProducts e buyProduct
-
No cliente:
-
Fazer testes de integração das operações implementadas
-
Testar casos mais importantes
-
Não esquecer os casos com argumentos incorretos: null, "", valores inesperados, etc
-
Os testes de integração correm com mvn verify no cliente