Avançar para a área de conteúdo

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Todas as informações enviadas são seguras.

  • Fechar [x]

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Todas as informações enviadas são seguras.

  • Fechar [x]

Serviços Web em Java: Explorando Axis2: AXIOM

O modelo de objeto do documento AXIOM é a base dos serviços Web Apache Axis2

Dennis Sosnoski, Consultant, Sosnoski Software Solutions, Inc.
Author photo
Dennis Sosnoski é um consultor e instrutor especializado em XML e serviços da Web baseados em Java. Sua experiência em desenvolvimento de software profissional se estende por mais de 30 anos, sendo que nos últimos 10 focou tecnologias XML e Java do lado do servidor. Dennis é o desenvolvedor líder da estrutura de software livre JiBX XML Data Binding e a estrutura de serviços da Web associada JiBX/WS, assim como um committer na estrutura de serviços da Web Apache Axis2. Também foi um dos membros do Grupo de Especialistas para as especificações JAX-WS 2.0 e JAXB 2.0. O material para a série Serviços da Web Java é baseado nas aulas de treinamento de Dennis.

Resumo:  A estrutura de serviços Web do Apache Axis2 foi desenvolvida sobre o novo modelo de documento AXIOM XML para permitir o processamento eficiente de mensagens SOAP. Diferentemente dos modelos de documento convencionais, o AXIOM desenvolve a representação do documento apenas na memória, à medida que vai sendo acessado. Entenda por que essa construção on demand é uma ótima abordagem para o processamento SOAP, e como os anexos XOP/MTOM, a ligação de dados e o desempenho se encaixam nesse quadro.

Visualizar mais conteúdo nesta série

Data:  30/Nov/2006
Nível:  Intermediário
Atividade:  2910 visualizações
Comentários:  


Mais um modelo de documento?

O Apache Axis2 1.1 foi lançado e oferece interessantes recursos novos para os fãs da longa série Apache de estruturas de serviços Web. Vamos tratar do Axis2 em si em um artigo futuro, mas este artigo vai a fundo no modelo de documento XML AXIs Object Model (AXIOM) que fica no núcleo do Axis2. O AXIOM é uma das principais inovações por trás do Axis2, e uma das razões por que este oferece o potencial para desempenho substancialmente melhor do que o Axis original. Este o artigo o guiará sobre como o AXIOM funciona, como as várias partes do Axis2 se desenvolvem no AXIOM e termina com uma olhada no desempenho do AXIOM em comparação com outros™ modelos de objeto de documento em Java.

Os modelos de documento são uma abordagem usada comumente no processamento XML, e há muitos recursos diferentes à disposição para o desenvolvimento Java, incluindo várias implementações da especificação original W3C DOM, JDOM, dom4j, XOM, e outras. Cada modelo afirma ter certas vantagens em relação aos outros, seja no desempenho, flexibilidade, seja na aderência rígida ao padrão XML, e cada uma tem seus defensores. Por que, então, o Axis2 precisava de um novo modelo? A resposta está em como as mensagens SOAP são estruturadas e, especialmente, em como são acrescentadas extensões à estrutura SOAP básica.

Introdução ao SOAP

O SOAP em si é realmente só um wrapper fino ao redor de uma carga útil de aplicativos XML. A Listagem 1 dá uma amostra, na qual as únicas partes realmente definidas pelo SOAP são os elementos com o prefixo soapenv. A maior parte do documento são os dados do aplicativo que compõem o conteúdo do elemento soapenv:Body.


Listagem 1. Amostra de SOAP
                
                <soapenv:Envelope
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <soapenv:Header/> <soapenv:Body> <matchQuakes
                xmlns="http://seismic.sosnoski.com/types">
                <min-date>2001-01-06T11:10:43.446Z</min-date>
                <max-date>2001-10-24T19:49:13.812Z</max-date>
                <min-long>-150.94307</min-long>
                <max-long>-22.594208</max-long>
                <min-lat>-11.44651</min-lat>
                <max-lat>55.089058</max-lat>
                </matchQuakes> </soapenv:Body>
                </soapenv:Envelope> 

Apesar da simplicidade do wrapper SOAP básico, ele oferece o potencial de extensões ilimitadas usando um componente opcional chamado de cabeçalho. O cabeçalho fornece um local para acrescentar todos os tipos de metadado que acompanharão os dados de aplicativo sem serem vistos pelo aplicativo (é possível incluir dados de aplicativo no cabeçalho, mas não há um caso suficientemente forte para fazer isso em vez de simplesmente usar o corpo para dados de aplicativo). Extensões desenvolvidas no SOAP (como toda a família WS-*) podem usar o cabeçalho para seus próprios fins sem afetar o aplicativo. Isso permite que as extensões operem como complementos, nos quais as funções estendidas específicas de que o aplicativo precisa podem ser simplesmente selecionadas no momento da implementação em vez de serem incluídas no código.

A Listagem 2 mostra os mesmos dados de aplicativo da amostra encontrada na Listagem 1 de SOAP, mas com informações de WS-Addressing incluídas. Embora a mensagem SOAP original provavelmente só fosse utilizável por transporte HTTP (visto que o HTTP fornece uma conexão bidirecional para que uma resposta imediata seja enviada de volta ao cliente), a versão da Listagem 2 poderia operar em outros protocolos, pois inclui os metadados de resposta diretamente na mensagem SOAP de solicitação. Seria fácil até mesmo ter uma etapa de armazenar e encaminhar envolvida no processamento da mensagem na Listagem 2 visto que os metadados fornecem informações de alvo de solicitação e de alvo de resposta.


Listagem 2. Amostra SOAP com WS-Addressing
                 <soapenv:Envelope
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:wsa="http://www.w3.org/2005/08/addressing">
                <soapenv:Header>
                <wsa:To>http://localhost:8800/axis2/services/SeisAxis2XBean</wsa:To>
                <wsa:ReplyTo>
                <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
                </wsa:ReplyTo>
                <wsa:MessageID>urn:uuid:97AE2B17231A8584D811537402403691</wsa:MessageID>
                </soapenv:Header> <soapenv:Body> <matchQuakes
                xmlns="http://seismic.sosnoski.com/types">
                <min-date>2000-03-28T13:13:08.953Z</min-date>
                <max-date>2001-03-11T02:26:54.283Z</max-date>
                <min-long>-81.532234</min-long>
                <max-long>65.25895</max-long>
                <min-lat>-14.234512</min-lat>
                <max-lat>57.174187</max-lat>
                </matchQuakes> </soapenv:Body>
                </soapenv:Envelope> 

O dilema do modelo de documento

Visto que a função básica do cabeçalho SOAP é permitir que metadados arbitrários sejam acrescentados à mensagem, é importante que as estruturas SOAP sejam capazes de aceitar qualquer coisa que uma extensão decida acrescentar. Falando de forma geral, o modo mais fácil de trabalhar com XML arbitrário é usando um modelo de documento de uma forma ou outra. Afinal de contas, essa é a razão de ser de um modelo de documento -- representar fielmente o XML sem suposições sobre a forma daquele XML.

Mas modelos de documento não são um modo muito eficiente de trabalhar com XML que é usado para trocar dados entre aplicativos. Os dados de aplicativo normalmente têm uma estrutura predefinida, e a maioria dos desenvolvedores prefere trabalhar com esses dados na forma de objetos de dado em vez de XML puro. O trabalho de converter entre objetos de dado e XML fica no âmbito do que é chamado de ligação de dados. A ligação de dados não só é mais conveniente para os desenvolvedores do que trabalhar com um modelo de documento, mas também é muito mais eficiente em termos de desempenho e uso de memória.

Assim, a maioria dos aplicativos decide usar ligação de dados para trabalhar com a carga útil de aplicativo da mensagem SOAP, mas a abordagem do modelo de documento é melhor para trabalhar com os metadados presentes no cabeçalho. A abordagem ideal seria combinar as duas técnicas dentro da estrutura SOAP, mas os modelos de documento normais não são configurados para permitir isso. Eles esperam trabalhar com um documento inteiro, ou, pelo menos, uma subárvore inteira de documento. Não são configurados para trabalhar apenas com partes selecionadas de um documento, como é mais adequado no SOAP.

Pull em árvore AXIOM

Além do AXIOM, há outra mudança entre o Axis e o Axis2. Enquanto o Axis original usava um analisador padrão em estilo push (SAX) para processar XML, o Axis2 usa um analisador estilo pull (StAX). Na abordagem push, o analisador fica no controle da operação de análise -- você lhe dá um documento para analisar e uma referência de manipulador. Ele usa então o manipulador para retornos de chamada no seu código ao processar o documento de entrada. O seu código manipulador pode usar as informações passadas pelos retornos de chamada, mas não pode afetar a análise (exceto ao gerar uma exceção). Por outro lado, na abordagem pull o analisador é na verdade um agente iterativo para percorrer os componentes de um documento on demand.

Tanto a abordagem push como a pull tem seus usos, mas o estilo pull tem um grande benefício no que se refere a XML que contenha componentes logicamente separados (como o SOAP). Com um analisador pull, o código que manipula uma parte do documento pode analisar apenas o que ele precisa e daí liberar o analisador para o que quer que venha a seguir no processamento do documento.

O AXIOM foi desenvolvido sobre uma interface de analisador pull StAX. O AXIOM fornece um modelo de documento virtual que ele expande on demand, construindo apenas a parte da representação de modelo de documento de estrutura de árvore solicitada pelo aplicativo cliente. Esse modelo de documento virtual trabalha no nível dos elementos do documento XML. é criada uma representação de elemento quando o analisador relata a tag de início do elemento, mas a forma inicial daquele elemento é essencialmente apenas um shell que contém uma referência ao analisador. Se o aplicativo precisar obter detalhes sobre o conteúdo do elemento, ele simplesmente solicita as informações chamando um método de interface (como o método org.apache.axiom.om.OMContainer.getChildren()). O elemento cria então o conteúdo-filho a partir do analisador em resposta à chamada de método.

Visto que o analisador libera os dados na ordem do documento (os mesmos itens de ordem aparecem no texto do documento XML), a construção on demand implementada pelo AXIOM exige um manuseio inteligente. Por exemplo, é normal ter múltiplos elementos em um estado incompleto (sob construção), mas esses elementos precisam estar todos em uma linha direta de herança. Em termos de classificação padrão do diagrama de árvore do XML com o elemento raiz no topo, os elementos incompletos sempre estarão na linha abaixo à direita da árvore. à medida que o aplicativo for solicitando mais dados, a árvore vai crescer para a direita, e os elementos inferiores serão concluídos primeiro.


Trabalhando com o AXIOM

Todos os modelos de documento XML têm muito em comum no que se refere aos seus APIs (o que não é surpresa, visto que todos trabalham com os mesmos dados subjacentes), mas cada um tem algumas manhas que o distingue dos outros. O W3C Document Object Model (DOM) original foi projetado para compatibilidade entre linguagens e entre plataformas, de modo que ele se desenvolve sobre interfaces e evita usar coleções específicas de Java em favor das suas próprias versões. O JDOM usa classes concretas em vez de interfaces e incorpora as classes de coleções padrão Java para um API que muitos desenvolvedores Java consideram mais amigável que o DOM. O dom4j combina interfaces como as do DOM com classes de coleções Java para um obter um API muito flexível que oferece muita potência -- a custo de certa complexidade.

O AXIOM tem muito em comum com esses outros modelos de documento. Também tem algumas diferenças significativas relacionadas com seu processo de desenvolvimento on-demand, além de alguns recursos especializados para dar suporte ao seu uso em serviços Web.

O AXIOM em ação

O API do AXIOM é provavelmente mais próximo do DOM no geral, mas tem suas manhas. Por exemplo, os métodos de acesso são projetados para uso de instâncias java.util.Iterator para acesso a componentes (como retornado por org.apache.axiom.om.OMContainer.getChildren() e métodos relacionados), em vez de alguma forma de lista. Em vez de indexar em uma lista de componentes, a navegação usa os métodos org.apache.axiom.om.OMNode.getNextOMSibling() e org.apache.axiom.om.OMNode.getPreviousOMSibling() para se mover sequencialmente pelos nós em um nível da árvore de documento (similar ao DOM nesse aspecto). Essa estruturação do acesso e métodos de navegação combinam com o modo de funcionamento da construção de árvore on-demand, visto que significa que o AXIOM lhe permite mover-se para o primeiro filho do seu elemento inicial sem ter de primeiro processar todos os elementos-filhos.

Como o DOM e o dom4j, o AXIOM define o API usado para acessar e manipular a representação de árvore usando interfaces. A distribuição AXIOM inclui várias implementações especializadas diferentes dessas interfaces. Uma implementação (no pacote org.apache.axiom.om.impl.dom) tem cabeçalho duplo, suportando interfaces AXIOM e DOM com as mesmas classes de implementação. Isso pode ser útil em vista do número de complementos de serviços Web que esperam trabalhar com a visualização DOM dos dados. Para uso mais geral, o pacote org.apache.axiom.om.impl.llom fornece uma implementação baseada em listas vinculadas de objetos (a parte "ll" do nome do pacote). Há também extensões das interfaces org.apache.axiom.om básicas e as implementações na árvore de pacote org.apache.axiom.soap que foram customizadas para uso com mensagens SOAP.

Para uma olhada rápida no API AXIOM em ação, veremos algumas amostras do código usado para teste de desempenho do AXIOM em comparação com outros modelos de documento. A Listagem 3 apresenta a primeira amostra, baseada no código usado para criar a representação AXIOM de um documento de entrada. Como no caso do DOM e do dom4j, antes de fazer qualquer coisa com o AXIOM você precisa de um factory que construa os objetos de componente do modelo. O código da Listagem 3 seleciona a implementação da lista vinculada básica das interfaces do AXIOM usando a implementação org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory da interface org.apache.axiom.org.OMFactory. A interface factory inclui métodos para criar um documento diretamente a partir de várias fontes, e para criar componentes individuais da representação de documento XML. A Listagem 3 usa o método para criar um documento a partir de um fluxo de entrada. O objeto retornado pelo método build() é na verdade uma instância de org.apache.axiom.om.OMDocument, embora isso não seja especificado por esse código.


Listagem 3. Analisando um documento no AXIOM
                 import org.apache.axiom.om.*; import
                org.apache.axiom.om.impl.builder.StAXOMBuilder; import
                org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory; ... 
                private
                XMLInputFactory m_parserFactory = XMLInputFactory.newInstance(); 
                private OMFactory
                m_factory = new OMLinkedListImplFactory(); ... protected Object build
                (InputStream in) { Object doc = null; try { XMLStreamReader reader =
                m_parserFactory.createXMLStreamReader(in); StAXOMBuilder builder = new
                StAXOMBuilder(m_axiomFactory, reader); doc = builder.getDocument(); } 
                catch (Exception ex) { ex.printStackTrace(System.out); System.exit(0); } 
                return doc; } 

A Listagem 3 usa a classe org.apache.axiom.om.impl.builder.StAXOMBuilder para criar a representação de documento ao analisar um fluxo de entrada. Isso cria apenas uma instância do analisador StAX e a estrutura básica do documento antes de retornar, deixando o analisador posicionado dentro do elemento-raiz do documento, com o restante da representação do documento para ser criada depois, se necessário. O AXIOM não precisa ser criado usando um analisador StAX. De fato, org.apache.axiom.om.impl.builder.SAXOMBuilder é uma implementação parcial de um construtor com base no analisador push SAX. Mas se você o construir de qualquer outra maneira, não terá os benefícios da construção on-demand.

A Listagem 4 mostra o código usado para "caminhar" pelos elementos em uma representação do documento e acumula informações de resumo (a contagem dos elementos, a contagem e comprimento total do texto de valor do atributo e a contagem e comprimento total do conteúdo de texto). O método walk() na parte inferior faz um documento ser resumido, junto com a estrutura de dados de resumo, enquanto o método walkElement() no alto processa um elemento (chamando a si mesmo de forma recorrente para processar os elementos-filhos).


Listagem 4. Navegando no AXIOM
                 /** * Walk subtree for element. This recursively walks through
                the document * nodes under an element, accumulating summary information.
                * * @param
                element element to be walked * @param summary document summary 
                information */
                protected void walkElement(OMElement element, DocumentSummary summary) { 
                // include
                attribute values in summary for (Iterator iter = 
                element.getAllAttributes();
                iter.hasNext();) { OMAttribute attr = (OMAttribute)iter.next();
                summary.addAttribute(attr.getAttributeValue().length()); } // loop 
                through children 
                for (Iterator iter = element.getChildren(); iter.hasNext();) { // handle 
                child by
                type OMNode child = (OMNode)iter.next(); int type = child.getType(); if 
                (type ==
                OMNode.TEXT_NODE) { summary.addContent(((OMText)child).getText().length
                ()); } else
                if (type == OMNode.ELEMENT_NODE) { summary.addElements(1);
                walkElement((OMElement)child, summary); } } } /** * Walk and summarize 
                document.
                This method walks through the nodes * of the document, accumulating 
                summary
                information. * * @param doc document representation to be walked * @param 
                summary
                output document summary information */ protected void walk(Object doc,
                DocumentSummary summary) { summary.addElements(1);
                walkElement(((OMDocument)doc).getOMDocumentElement(), summary); } 

Por fim, a Listagem 5 mostra o código usado para escrever a representação do documento em um fluxo de saída. O AXIOM define muitos métodos de saída como parte da interface OMNode, incluindo variações de destino (como fluxo de saída, gravador normal de caractere ou gravador de fluxo StAX), com e sem informações de formatação, e com e sem a habilidade de acessar a representação do documento depois de ser gravada (o que exige que a representação inteira seja criada, se já não tiver sido). A interface OMElement define outro modo de acessar informações do documento, obtendo um analisador StAX do elemento. Essa habilidade de fazer o pull do XML a partir da representação usando um analisador oferece uma simetria interessante, e funciona bem quando a representação do AXIOM é criada on demand (visto que o analisador em uso para criar a representação pode então ser retornado diretamente).


Listagem 5. Gravando um documento a partir do AXIOM
                 /** * Output a document as XML text. * * @param doc
                document representation to be output * @param out XML document output 
                stream */
                protected void output(Object doc, OutputStream out) { try {
                ((OMDocument)doc).serializeAndConsume(out); } catch (Exception ex) {
                ex.printStackTrace(System.err); System.exit(0); } } 

O AXIOM fornece alguns métodos básicos para modificar um componente de documento existente (como OMElement.setText() para configurar o conteúdo de um elemento para um valor de texto). Se você estiver começando do zero, precisará criar diretamente novas instâncias de componentes. Visto que o API AXIOM se baseia em interfaces, ele usa factories para criar implementações reais dos componentes.

Para mais detalhes sobre o API AXIOM, veja os links do tutorial de AXIOM e JavaDocs na seção de Recursos.

MTOM no AXIOM

Um dos recursos mais interessantes do AXIOM é seu suporte integrado aos padrões W3C XOP e MTOM, usados nas versões mais recentes dos anexos SOAP. Essas duas normas trabalham juntas: o XML-binary Optimized Packaging (XOP) fornece um modo de os documentos XML incluírem logicamente blobs de dados binários arbitrários e o MTOM (SOAP Message Transmission Optimization Mechanism) aplica a técnica XOP às mensagens SOAP. O XOP e o MTOM são recursos fundamentais na nova geração de estruturas de serviços Web visto que finalmente fornecem suporte a anexos interoperáveis e acabam com os problemas atuais nessa área.

O XOP trabalha com conteúdo de dados de caracteres codificados em base64. A codificação em base64 transforma os valores de dados arbitrários em caracteres ASCII imprimíveis usando um caractere ASCII para representar cada seis bits dos dados originais. Visto que os dados binários em geral não podem ser incluídos no XML (o XML trabalha apenas com caracteres, não bytes puros; até mesmo vários códigos de caractere não são permitidos no XML), a codificação em base64 é útil para incluir dados binários em mensagens XML.

O XOP substitui o texto real em base64 por um elemento especial "Incluir" do espaço de nomes XOP. O elemento Incluir apresenta um URI que identifica uma entidade separada (fora do documento XML) que são os dados reais a serem incluídos no documento XML. Normalmente esse URI identifica um bloco separado dentro da mesma transmissão como documento XML (embora não seja um requisito ele fazer isso, o que oferece benefícios potenciais para troca de documentos por meio de documentos intermediários ou de armazenamento). Os benefícios de substituir o texto em base64 com uma referência aos dados puros são um tamanho de documento um pouco menor (até 25% menor do que em codificações normais de caracteres) e processamento mais rápido sem overhead de codificação e decodificação dos dados em base64.

O MTOM é desenvolvido sobre XOP, primeiro definindo um modelo abstrato de como o XOP pode ser usado para mensagens SOAP, depois especializando esse modelo para uso com o pacote MIME Multipart/Related e finalmente aplicando-o ao transporte HTTP. No conjunto, isso fornece um modo padrão de aplicar o XOP a mensagens SOAP usando o amplamente usado transporte HTTP.

O AXIOM suporta o XOP/MTOM pela interface org.apache.AXIOM.om.OMText e as implementações dessa interface. OMText define métodos para dar suporte a itens de texto apoiados em dados binários (na forma de javax.activation.DataHandler, parte do Java Activation API amplamente usado para suporte a anexos em estruturas de serviço Web Java), junto com um sinalizador "otimizar" que diz se o item pode ser processado usando XOP. A implementação org.apache.AXIOM.om.impl.llom.OMTextImpl acrescenta uma ID de conteúdo compatível com MTOM que pode ser configurada quando uma instância da classe é criada, ou então gerada automaticamente se não for configurada.

A Listagem 6 exibe uma amostra de como criar uma mensagem usando XOP/MTOM em AXIOM. Esse código é tirado de um exemplo de teste de desempenho que usa serialização Java para converter uma estrutura de dados de resultado em um array de bytes, e daí retorna esse conjunto como anexo.


Listagem 6. Criando uma mensagem XOP/MTOM
                 public OMElement matchQuakes(OMElement req) { Query query =
                new Query(); Iterator iter = req.getChildElements(); try { ... // 
                retrieve the matching quakes Response response = QuakeBase.getInstance()
                .handleQuery(query); //
                serialize response to byte array ByteArrayOutputStream bos = new
                ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream
                (bos);
                oos.writeObject(response); byte[]byts = bos.toByteArray(); // generate 
                response
                structure with reference to data ByteArrayDataSource ds = new
                ByteArrayDataSource(byts); OMFactory fac = OMAbstractFactory.getOMFactory
                ();
             OMNamespace ns = fac.createOMNamespace("http://seismic.sosnoski.com/types", 
             "qk");
                OMElement resp = fac.createOMElement("response", ns); OMText data =
                fac.createOMText(new DataHandler(ds), true); resp.addChild(data); return 
                resp; }
                catch (ParseException e) { e.printStackTrace(); } catch (IOException e) {
                e.printStackTrace(); } return null; } 

Embora o código da Listagem 6 gere uma resposta que pode ser enviada usando o XOP/MTOM, na versão atual do Axis2, o suporte a XOP/MTOM fica desabilitado como padrão. Para ativá-lo, é preciso incluir um parâmetro <parameter name="enableMTOM">true</parameter> no arquivo axis2.xml do Axis2 ou no arquivo services.xml para o seu serviço. Forneceremos o código completo desse exemplo como parte de comparações de desempenho mais à frente, mas agora concluiremos com uma amostra do XOP/MTOM em uso.

A Listagem 7 mostra a estrutura da mensagem de resposta gerada pelo serviço da Listagem 6, com e sem XOP/MTOM ativado (sem os cabeçalhos MIME e o anexo binário real, no primeiro caso, e com a maior parte dos dados deixados de fora, no segundo caso).


Listagem 7. Mensagem de resposta com e sem XOP/MTOM
                 <?xml version='1.0' encoding='UTF-8'?>
                <soapenv:Envelope
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <soapenv:Header /> <soapenv:Body> <qk:response
                xmlns:qk="http://seismic.sosnoski.com/types"
                xmlns:tns="http://ws.apache.org/axis2"> <xop:Include
                href="cid:1.urn:uuid:966CA4565647BEBA3D115028348657315@apache.org"
                xmlns:xop="http://www.w3.org/2004/08/xop/include" />
                </qk:response> </soapenv:Body>
                </soapenv:Envelope> [actual binary data follows as separate MIME part
                with referenced content id] <?xml version='1.0' encoding='UTF-8'?>
                <soapenv:Envelope
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <soapenv:Header /> <soapenv:Body> <
                qk:response
                xmlns:qk="http://seismic.sosnoski.com/types"
                xmlns:tns="http://ws.apache.org/axis2">rO0ABXNyACdjb20uc29zb...
                </qk:response>
                </soapenv:Body> </soapenv:Envelope> 

-

Ganchos de ligação de dados

A maioria dos desenvolvedores que trabalham com serviços Web precisam trabalhar com dados na forma de objetos Java, em vez de documentos XML (ou mesmo modelos de documento, como o AXIOM). As estruturas de última geração, como Axis e JAX-RPC, implementavam suas próprias formas de ligação de dados para converter entre XML e objetos Java, mas essa era uma solução muito limitada. As implementações de ligação de dados em estruturas de serviços Web em geral não podiam competir com estruturas especializadas de ligação de dados, de modo que usuários que quisessem melhor controle sobre o manuseio de XML tinham de "colar" as estruturas por meio de ineficientes códigos de conversão. Em vista dessas questões, o Axis2 foi projetado desde o início para dar suporte a ligação de dados por "plug-in" usando uma grande variedade de estruturas de ligação de dados.

O suporte à ligação de dados usa extensões customizadas para a ferramenta WSDL2Java incluída no Axis2. Essa ferramenta gera um código de ligação do Axis2 com base na descrição de serviço WSDL na forma de stub para o lado de cliente ou um receptor de mensagem do lado do servidor. O stub do lado do cliente funciona como proxy para fazer chamadas ao serviço, definindo chamadas de método que implementam operações de serviço. O receptor de mensagens do lado do servidor funciona como proxy para o cliente, chamando o método de serviço real definido pelo usuário. Quando a ligação de dados é solicitada na linha de comando WSDL2Java, a ferramenta chama a extensão de estrutura de ligação de dados especificada para gerar o código no stub ou receptor de mensagens que converte entre OMElement e objetos Java. No caso do stub, os objetos Java (ou valores primitivos) são passados na chamada de método e o XML convertido é enviado para o servidor como solicitação. O XML retornado é então reconvertido em objeto Java, que é então retornado como resultado da chamada de método. O receptor de mensagens no lado do servidor faz as mesmas conversões em reverso.

No lado de entrada ou unmarshalling (conversão de XML recebido em objetos Java), o manuseio é fácil. A carga útil do documento XML a ser convertida em objetos Java está disponível na forma de OMElement, e a estrutura de ligação de dados simplesmente precisa processar os dados daquele elemento. OMElement fornece acesso aos dados do elemento na forma de StAX javax.xml.stream.XMLStreamReader, que a maioria das estruturas de ligação de dados atuais podem usar diretamente como entrada.

O lado de saída ou de marshalling (conversão de objetos Java em XML transmitido) é um pouco mais difícil. O principal objetivo o AXIOM é evitar a construção de uma representação total dos dados do XML a menos que isso seja absolutamente necessário. Para suportar esse princípio no marshalling, é preciso haver um jeito de a estrutura de ligação de dados ser invocada apenas quando necessário. O AXIOM manuseia isso usando um org.apache.AXIOM.om.OMDataSource como wrapper for para a conversão de ligação de dados. OMDataSource define os métodos para gravar o conteúdo do wrapper usando um dos métodos suportados pelo AXIOM (para java.io.OutputStream, java.io.Writer ou StAX javax.xml.stream.XMLStreamWriter), junto com outro método que retorna uma instância de analisador para o conteúdo do wrapper. Uma implementação OMElement pode usar uma instância de OMDataSource para fornecer dados on demand, e a interface OMFactory fornece um método para criar esse tipo de elemento.


Desempenho

Vamos concluir nossa análise do AXIOM com uma olhada rápida no desempenho. Na época em que este artigo é escrito, o AXIOM está disponível no release 1.1 o que significa que as interfaces descritas aqui devem estar estáveis. Por outro lado, o desempenho está sujeito a mudanças ao longo do tempo à medida que o código de implementação em si é modificado. Não esperamos ver grandes mudanças no desempenho do AXIOM em relação a outros modelos de documento, mas é possível que alguns detalhes mudem.

Para comparar o AXIOM com outros modelos de documento, atualizamos os códigos de um estudo anterior sobre modelos de documento (veja a seção de Recursos), acrescentando o AXIOM e mais um novo modelo de documento (XOM), convertendo o código para usar o padrão de analisador StAX em vez do padrão antigo SAX e mudando para o método de cronometragem melhorado System.nanoTime() introduzido no Java 5. O código de teste de desempenho primeiro lê para a memória os documentos a serem usados no teste, daí executa uma sequência de operações nos documentos. Primeiro, várias cópias de representações do documento são construídas a partir dos analisadores, e cada objeto de documento resultante é retido. A seguir, cada objeto de documento precisa "caminhar", o que significa que o código varre a inteira representação do documento (incluindo todos os atributos, valores e conteúdo de texto). Por fim, cada objeto de documento é gravado em um fluxo de saída. O tempo é gravado para cada operação individual e sua média é tirada no fim da execução de teste.

Visto que o principal foco do AXIOM (em especial seu uso no Axis2) é no manuseio de mensagens SOAP, usamos três casos de teste de mensagem SOAP diferentes para verificar o desempenho. O primeiro é uma resposta de amostra de um teste de desempenho de serviço Web que dá informações sobre terremotos dentro de um intervalo específico de tempo e latitude/longitude ("quakes", 18 KB). Este documento contém elementos muito repetidos com certo aninhamento e muito uso de atributos. O segundo é uma amostra maior do teste de interoperabilidade Microsoft WCF, que consiste em uma única estrutura repetida com pequenas variações de valores ("persons", 202 KB). Esse documento tem elementos-filhos com conteúdo de texto, mas sem o uso de atributos. O terceiro caso de teste é uma coleção de 30 pequenos documentos de mensagem SOAP tirados de alguns testes antigos de interoperabilidade (tamanho total: 19 KB). Todos os espaços em branco de formatação foram removidos dos documentos de teste para tornar os documentos representativos do XML trocado por serviços reais de produção (que em geral desligam a formatação para manter pequeno o tamanho das mensagens).

As tabelas abaixo mostram o tempo médio necessário para 50 passagens em cada documento. O ambiente de teste foi um sistema de notebook Compaq com processador AMD Turion 1600 MHz ML-30 e 1.5 GB de RAM, executando o 1.5.0_07-b03 JVM da Sun no Mandriva 2006 Linux. Testamos o AXIOM 1.0, dom4j 1.6.1, JDOM 1.0, Xerces2 2.7.0 e XOM da distribuição Nux 1.6. Os construtores customizados de analisadores StAX foram usados no dom4j, JDOM e Xerces2, e o construtor de analisador Nux StAX foi usado no XOM. Todos os testes usaram o analisador Woodstox StAX 2.9.3.

A Figura 1 mostra a soma dos tempos médios necessários para as primeiras duas etapas da sequência de teste, construindo um documento a partir do analisador, e fazendo a representação de documento caminhar para verificar o conteúdo. Se você observar a primeira etapa do isolamento (tempo não mostrado aqui), o AXIOM funciona muito melhor que os outros modelos de documento, pelo menos para os primeiros dois documentos. Contudo, isso apenas mostra que o AXIOM está trabalhando como esperado e não está realmente construindo o documento completo até que seja necessário. Queríamos usar o tempo usado para realmente construir a representação completa na memória para ter uma comparação justa, e é por isso que os dois tempos nessa tabela foram somados.


Figura 1. Tempos para construir e expandir documentos (em milissegundos)
Times to build and expand documents

Como visto na Figura 1, o AXIOM é mais lento no geral do que qualquer outro modelo de documento testado, exceto o Xerces2.

Vários dos modelos de documento mostraram problemas de desempenho no que se refere à coleta de pequenos documentos ("soaps"). O Xerces2 se saiu especialmente mal nesse caso, mas o AXIOM também mostrou bastante overhead que é, provavelmente, a questão mais problemática revelada por essa tabela. Mensagens pequenas são comuns em muitos serviços Web e o AXIOM deve poder processá-las de forma eficiente. Visto que o AXIOM foi realmente projetado em relação à expansão da árvore on-demand, o tempo dos dois documentos maiores não é uma grande preocupação visto que estão pelo menos próximos dos outros modelos de documento.


Figura 2. Tempo para gravar os documentos (em milissegundos)
Times to write documents

A Figura 2 mostra os tempos médios de gravação de documentos para um fluxo de saída usando cada modelo. Aqui, o Xerces2 tem o melhor tempo por uma diferença substancial (mas não o bastante para compensar seu desempenho ruim na etapa de construção; as escalas das duas tabelas são diferentes), enquanto o AXIOM é o pior. Novamente, o AXIOM parece se sair especialmente ruim com documentos pequenos.


Figura 3. Tamanho de memória dos documentos (em KB)
Document memory sizes

Por fim, a Figura 3 mostra a memória usada por cada estrutura para representar os documentos. Novamente, o dom4j é o melhor e o AXIOM o pior por uma diferença considerável. Parte do desempenho ruim do AXIOM no uso da memória se deve ao analisador ser referenciado pelo documento construído de modo que a instância do analisador é mantida enquanto a instância do documento está em uso. Novamente, essa é provavelmente parte da razão por que o AXIOM se sai especialmente mal com documentos pequenos. Contudo, os objetos usados pelo AXIOM como componentes do documento também são consideravelmente maiores do que seus equivalentes em outros modelos de documento, e essa diferença é provavelmente a razão de o AXIOM usar muito mais espaço mesmo para os dois maiores documentos de teste (nos quais o overhead de tamanho fixo do analisador e outras estruturas de dados têm proporção menor de uso total da memória).

Se você somar os tempos das primeiras duas tabelas, o líder geral no desempenho é o dom4j, enquanto o "lanterninha" do desempenho foi o Xerces2 (com o AXIOM só um pouquinho à frente do último). No que se refere ao uso da memória, o dom4j é também o melhor, mas nessa disputa o AXIOM é o perdedor absoluto. Parece ruim para o AXIOM?

Seria ruim se a representação completa da árvore sempre fosse criada, mas lembre que o objetivo do AXIOM é que normalmente não é necessária a representação completa. A Figura 4 mostra o tempo apenas da construção inicial do documento no AXIOM, em comparação com o tempo correspondente para outros modelos de documento construírem a representação do documento. Aqui, o AXIOM é muito mais rápido que os outros (rápido demais até para registrar, no caso dos dois documentos maiores). O mesmo tipo de comparação se aplica ao lado da memória. O resultado líquido é que se você precisar trabalhar apenas com parte do modelo de documento (a "primeira" parte, em termos de ordem de documento), o AXIOM terá um ótimo desempenho.


Figura 4. Construção inicial do documento
Document memory sizes

O Axis2

Este artigo foi escrito como análise detalhada do modelo de objeto de documento do AXIOM no núcleo do Axis2. O AXIOM inclui algumas inovações interessantes, em especial em termos de sua abordagem integrada on demand para construir a representação completa. Não está completamente de acordo com outros modelos de documento Java quando se precisa de representação totalmente expandida. Seu desempenho com pequenos documentos é especialmente perturbador, mas a flexibilidade que ele fornece para processamento de serviços Web compensa muitas dessas preocupações.

Agora você sabe como o Axis2 gerencia representações de mensagens SOAP usando AXIOM, incluindo como ele passa XML para e de estruturas de ligação de dados. O próximo artigo analisa com o Axis2 dá suporte a diferentes trabalhos com estruturas de ligação de dados da perspectiva do usuário, incluindo amostras de código usando três das estruturas.



Download

DescriçãoNomeTamanhoMétodo de download
Source codej-java2.zip98KBHTTP

Informações sobre métodos de download


Recursos

Aprender

Obter produtos e tecnologias

  • Desenvolva seu próximo projeto de desenvolvimento com o software de teste IBM, disponível para download diretamente na developerWorks.

  • Obtenha mais informações e teste você mesmo o AXIOM fazendo o download dele no Apache AXIOM Project.

  • O modelo de objeto de documento dom4j é rápido, eficiente no uso da memória e também oferece grande extensibilidade.

  • O modelo de objeto de documento JDOM é conhecido por sua facilidade de uso.

  • O modelo de objeto de documento XOM protege os usuários contra erros comuns no uso do XML, enquanto oferece bom desempenho e eficiência no uso da memória.

  • O Nux é um projeto de software livre voltado para middleware de mensagens XML de alto rendimento que visa integrar os melhores componentes para o processamento XML em um único kit de ferramentas.

  • O Xerces2 é a implementação Apache do modelo de objeto de documento padrão W3C.

  • Obtenha as mais recentes informações e downloads do Apache Axis2.

  • O WoodStox é uma implementação de software livre do analisador pull StAX padrão.

Sobre o autor

Author photo

Dennis Sosnoski é um consultor e instrutor especializado em XML e serviços da Web baseados em Java. Sua experiência em desenvolvimento de software profissional se estende por mais de 30 anos, sendo que nos últimos 10 focou tecnologias XML e Java do lado do servidor. Dennis é o desenvolvedor líder da estrutura de software livre JiBX XML Data Binding e a estrutura de serviços da Web associada JiBX/WS, assim como um committer na estrutura de serviços da Web Apache Axis2. Também foi um dos membros do Grupo de Especialistas para as especificações JAX-WS 2.0 e JAXB 2.0. O material para a série Serviços da Web Java é baseado nas aulas de treinamento de Dennis.

Ajuda para Relatar Abuso

Relatar abuso

Obrigado. Esta entrada foi sinalizada para atenção do moderador.


Ajuda para Relatar Abuso

Relatar abuso

Falha no envio do Relatório de abuso. Tente novamente mais tarde.


developerWorks: Registre-se


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Selecione seu nome de exibição

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

(Deve possuir de 3 a 31 caracteres.)


Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Classificar este artigo

Comentários

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre
ArticleID=395716
ArticleTitle=Serviços Web em Java: Explorando Axis2: AXIOM
publish-date=11302006
author1-email=dms@sosnoski.com
author1-email-cc=jaloi@us.ibm.com

Conheça a IBM da sua cidade

Virtual Branch Office Brasil

A IBM está mais perto do que você imagina!


Tags

Help
Use o campo de pesquisa para encontrar todos os tipos de conteúdo no My developerWorks com essa tag.

Use a barra de rolagem para ver mais ou menos tags.

Tags populares mostra as principais tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Minhas tags mostra suas tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Use o campo de pesquisa para localizar todos os tipos de conteúdo no Meu developerWorks com essa tag. Tags populares mostra as tags principais para essa zona de conteúdo particular (por exemplo, tecnologia Java, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere). Minhas tags mostra as suas tags para essa zona de conteúdo em particular (por exemplo, tecnologia Java, Linux, WebSphere).