Desenvolvendo um Cliente Dinâmico Utilizando APIs JAX-WS
O JAX-WS (Java™ API for XML-Based Web Services) fornece suporte para chamada dinâmica de operações de terminal de serviço.
Sobre Esta Tarefa
O JAX-WS fornece uma nova API de cliente de Dispatch dinâmico que é mais genérico e oferece mais flexibilidade do que a DII (Dynamic Invocation Interface) baseada em JAX-RPC (Java API for XML-based RPC) existente. A interface do cliente Dispatch, javax.xml.ws.Dispatch, é um cliente orientado ao sistema de mensagens XML que é destinado a desenvolvedores XML avançados que preferem trabalhar no nível XML utilizando construções XML. Para gravar um cliente Dispatch, é necessário ter experiência com APIs do cliente Dispatch, os tipos de objetos suportados e o conhecimento das representações de mensagem para o arquivo WSDL (Web Services Description Language) associado.
A API Dispatch pode enviar os dados no modo PAYLOAD ou MESSAGE. Ao utilizar o modo PAYLOAD, o cliente Dispatch é responsável apenas por fornecer o conteúdo do <soap:Body> e o JAX-WS inclui a carga útil de entrada em um elemento <soap:Envelope>. Ao utilizar o modo MESSAGE, o cliente Dispatch é responsável por fornecer o envelope SOAP inteiro.
- javax.xml.transform.Source: Utilize os objetos de Origem para permitir que os clientes utilizem as XML APIs diretamente. É possível utilizar objetos de Origem com ligações SOAP e HTTP.
- Objetos JAXB: Utilize os objetos JAXB para que os clientes possam utilizar os objetos JAXB que são gerados a partir de um esquema XML para criar e manipular XML com aplicativos JAX-WS. Os objetos JAXB podem ser utilizados apenas com ligações SOAP e HTTP.
- javax.xml.soap.SOAPMessage: Utilize os objetos SOAPMessage para que os clientes possam trabalhar com mensagens SOAP. É possível utilizar apenas objetos SOAPMessage com as ligações SOAP versão 1.1 ou SOAP versão 1.2.
- javax.activation.DataSource: Utilize os objetos DataSource para que os clientes possam trabalhar com mensagens MIME (Multipurpose Internet Mail Extension). Utilize DataSource apenas com ligações HTTP.
Procedimento
Resultados
As portas dinâmicas do JAX-WS, que são aquelas incluídas usando o addPort de método de serviço, podem ter requisitos de memória adicionais iniciando no WebSphere Application Server Versão 8.0. Em liberações anteriores, uma instância única de uma porta dinâmica pode ser compartilhada entre diversas instâncias de serviço. Na versão 8.x, as portas dinâmicas estão agora com escopo definido para a instância do serviço que as incluiu. Se um cliente JAX-WS tiver diversas instâncias de serviço que referenciarem uma porta dinâmica do mesmo nome, essas instâncias não serão mais compartilhadas. Isso pode potencialmente aumentar os requisitos de memória para esse cliente. A memória usada pelas portas dinâmicas são liberadas quando a instância de serviço sair do escopo. Entretanto, se encontrar problemas relacionados ao uso de memória aumentado, é possível reverter o comportamento para que as portas dinâmicas estejam novamente compartilhadas entre as instâncias de serviço. Para fazer isso, configure a propriedade do sistema jaxws.share.dynamic.ports.enable para o valor true. Entretanto, note que fazer isso pode causar alguns problemas, como os anexos do conjunto de políticas serem aplicados incorretamente entre as portas dinâmicas compartilhadas. Se configurar esse sinalizador para true e encontrar alguns desses problemas, deverá remover a configuração do sinalizador.
Em liberações anteriores, se uma Ação SOAP não foi fornecida pelo aplicativo cliente Dispatch, a Ação SOAP correta não foi enviada na mensagem de saída. Em vez disso, a ação SOAP foi configurada para uma operação anônima. Iniciando no WebSphere Application Server Versão 8, se a Ação SOAP não foi fornecida pelo aplicativo cliente Dispatch, o ambiente de tempo de execução JAX-WS analisará a mensagem de saída. Ele determina a operação que está sendo chamada e usa essas informações para determinar o valor apropriado para a Ação SOAP. A resolução da operação da mensagem de saída baseia-se no Corpo SOAP e na codificação da mensagem, por exemplo, Doc/Lit/Bare, Doc/Lit/Wrapped. Como essa análise pode ser dispendiosa, uma propriedade pode ser configurada. Para desativar sempre a análise, configure a propriedade no nível do Sistema. Para desativar a análise basicamente por mensagem, configure a propriedade no Contexto de Mensagem de Solicitação JAX-WS. A propriedade é definida como uma org.apache.axis2.jaxws.Constants.DISPATCH_CLIENT_OUTBOUND_RESOLUTION constante com um valor de Sequência de jaxws.dispatch.outbound.operation.resolution.enable. O valor padrão da propriedade é nulo, o que é interpretado como a Sequência true, que ativa a resolução da operação de saída. Configurar a propriedade para false desativa a resolução de operação de saída. Se a análise estiver desativada, a Ação SOAP na mensagem de saída será configurada para uma operação anônima, tal como era feito em liberações anteriores. Se um cliente fornecer uma Ação SOAP por meio das propriedades JAX-WS javax.xml.ws.BindingProvider, SOAPACTION_USE_PROPERTY e SOAPACTION_URI_PROPERTY, a Ação SOAP será usada. Portanto, a análise da mensagem de saída não ocorre, independente da configuração da propriedade. Configurar uma Ação SOAP explicitamente pelo cliente é considerado uma boa prática, especialmente para o desempenho no provedor de serviços. Essa prática evita que a mensagem de entrada seja analisada, sendo roteada para a operação de terminal correta.
Exemplo
String endpointUrl = ...;
QName serviceName = new QName("http://com/ibm/was/wssample/echo/",
"EchoService");
QName portName = new QName("http://com/ibm/was/wssample/echo/",
"EchoServicePort");
/** Crie um serviço e inclua, pelo menos, uma porta a ele. **/
Service service = Service.create(serviceName);
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);
/** Crie uma instância Dispatch a partir de um serviço.**/
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,
SOAPMessage.class, Service.Mode.MESSAGE);
/** Crie o pedido SOAPMessage. **/
// redija uma mensagem de pedido
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
// Crie uma mensagem. Esse exemplo trabalha com SOAPPART.
SOAPMessage request = mf.createMessage();
SOAPPart part = request.getSOAPPart();
// Obtenha o SOAPEnvelope e os elementos header e body.
SOAPEnvelope env = part.getEnvelope();
SOAPHeader header = env.getHeader();
SOAPBody body = env.getBody();
// Construa a carga útil da mensagem.
SOAPElement operation = body.addChildElement("invoke", "ns1",
"http://com/ibm/was/wssample/echo/");
SOAPElement value = operation.addChildElement("arg0");
value.addTextNode("ping");
request.saveChanges();
/** Chame o terminal em serviço. **/
SOAPMessage response = dispatch.invoke(request);
/** Processe a resposta. **/