Labs SD >
O SOAP é o formato de mensagens para Web Services. Os envelopes podem ser transportados pela rede de diversas formas, mas a mais comum é através do protocolo HTTP. O SOAP é independente do protocolo de transporte.
Os documentos seguintes são mensagens SOAP correspondentes a um par pedido-resposta.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:hello"> <soapenv:Body> <ns1:sayHello> <ns1:name>friend</ns1:name> </ns1:sayHello> </soapenv:Body> </soapenv:Envelope> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:hello"> <soapenv:Body> <ns1:sayHelloResponse> <ns1:return>Hello friend!</ns1:return> </ns1:sayHelloResponse> </soapenv:Body> </soapenv:Envelope>
Uma mensagem SOAP é um documento XML
designado por envelope.
O cabeçalho header permite a composição de protocolos,
pois cada elemento de extensão indica a sua versão e
a opcionalidade da sua interpretação.
O corpo (body) contém os dados de negócio da mensagem ou
então o elemento Fault com informação de erro.
A SAAJ (SOAP with Attachments API for Java) é uma biblioteca que estende o XML DOM, adaptando-o para documentos XML que são mensagens SOAP. Isto significa que existem vários métodos específicos para tratar as mensagens.
Na biblioteca SAAJ, uma mensagem SOAP tem a seguinte estrutura:
A SOAPMessage contém várias partes.
A primeira parte é uma SOAPPart, que contém um SOAPEnvelope.
Um SOAPEnvelope contém um SOAPBody e opcionalmente um SOAPHeader.
Dentro destes, podem ser colocados SOAPElement.
Numa mensagem SOAP, os elementos devem ser sempre especificados
com espaço de nomes,
para evitar conflitos.
Os objectos da biblioteca SAAJ estão no pacote javax.xml.soap.*
O exemplo seguinte mostra como se constrói uma mensagem simples.
... MessageFactory mf = MessageFactory.newInstance(); SOAPMessage soapMessage = mf.createMessage(); SOAPPart soapPart = soapMessage.getSOAPPart(); SOAPEnvelope soapEnvelope = soapPart.getEnvelope(); SOAPBody soapBody = soapEnvelope.getBody(); Name name = soapEnvelope.createName("HelloWorld", "hw", "urn:helloworld"); SOAPElement element = soapBody.addChildElement(name); element.addTextNode( "hello text message" ); ... soapMessage.writeTo(System.out); System.out.println(); ...
Os exemplos seguintes mostram como modificar as mensagens SOAP e
como enviar mensagem SOAP directamente sem stubs.
Para complementar existem também exemplos das tecnologias base de XML:
SAX, DOM, XSD, XPath.
A biblioteca de Web Services para Java, JAX-WS,
tem um mecanismo que permite intercetar e
aceder diretamente às mensagens SOAP.
Um Handler é uma classe Java que implementa a interface javax.xml.ws.handler.soap.SOAPHandler.
O seguinte exemplo é um Handler básico. O principal método é o handleMessage() que é invocado de cada vez que chega ou parte uma mensagem:
package example.ws.handler; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; public class EmptyHandler implements SOAPHandler{ /** * Gets the names of the header blocks that can be processed by this Handler instance. * If null, processes all. */ public Set getHeaders() { return null; } /** * The handleMessage method is invoked for normal processing of inbound and * outbound messages. */ public boolean handleMessage(SOAPMessageContext smc) { return true; } /** The handleFault method is invoked for fault message processing. */ public boolean handleFault(SOAPMessageContext smc) { return true; } /** * Called at the conclusion of a message exchange pattern just prior to the * JAX-WS runtime dispatching a message, fault or exception. */ public void close(MessageContext messageContext) { } }
O retorno do método handleMessage() determina de que forma
prossegue o processamento da mensagem.
Se for 'true' o processamento deve prosseguir;
se for 'false' bloqueia o processamento da mensagem,
mudando-lhe o sentido e
fazendo-a voltar para o cliente.
A utilização de exceções permite modificar o normal processamento das mensagens SOAP:
A configuração dos Handlers é efectuada num ficheiro que define a cadeia de handlers.
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee"> <handler-chain> <handler> <handler-class>example.ws.handler.LoggingHandler</handler-class> </handler> </handler-chain> </handler-chains>
A configuração os Handlers é diferente no servidor e no cliente. Em ambos os casos não são necessárias alterações aos pom.xml.
Esta biblioteca é um módulo Maven com Handlers que podem ser usados em servidores e clientes.
Esta biblioteca poderá ser enriquecida com handlers adicionais (por exemplo, no projeto).
Este exemplo demonstra a forma como os SOAP Handlers acedem às mensagens XML dos Web Services.
Este exemplo demonstra os mecanismos de passagem de dados entre as diversas camadas de um Web Service:
Consultar os exemplos seguindo os comentários numerados #1, #2, #3, ... que seguem a sequência de uma invocação remota começando no cliente, passando pelo servidor e voltando ao cliente. Pelo caminho o token vai sendo acrescentado com mais dados.
O objetivo deste exercício é configurar o LoggingHandler para intercetar as comunicações.
Começar por supplier-ws:
@HandlerChain(file = "/supplier-ws_handler-chain.xml")
Configurar os handlers supplier-ws-cli:
Neste ponto as mensagens SOAP estão a ser capturadas à saída no cliente e à chegada no servidor.
Vamos agora criar um novo handler para validação temporal das mensagens:
Próximos passos:
Bom trabalho!
© Docentes de Sistemas Distribuídos,
Dep. Eng. Informática,
Técnico Lisboa