Trabalhando com Documentos XML
Nesta seção, você aprenderá sobre como executar o compilador de ligação JiBX e como usar JiBX no tempo de execução para trabalhar com documentos XML.
Executando o Compilador de Ligação JiBX
Para usar a definição de ligação gerada no trabalho com documentos XML, primeiro, você precisa executar a ferramenta do compilador de ligação JiBX. O compilador de ligação inclui bytecode em seus arquivos de classe compilados que realmente implementa as conversões para, e a partir de, XML, conforme especificado pela definição de ligação. Você deve executar o compilador de ligação toda vez que recompilar suas classes Java ou modificar a definição de ligação, portanto, geralmente é melhor incluir a etapa do compilador de ligação como parte do processo de construção padrão de seu projeto.
O compilador de ligação está incluído na distribuição JiBX como parte do jibx-bind.jar. A documentação de JiBX fornece detalhes integrais sobre as diferentes maneiras de executar o compilador de ligação, inclusive como você pode executá-lo no tempo de execução em vez de como parte da construção. JiBX também fornece plug-ins para o Eclipse e o IntelliJ IDEA que executam o compilador de ligação automaticamente quando você está trabalhando nesses IDEs.
Para os propósitos deste tutorial, vamos manter as coisas simples e simplesmente executar o compilador de ligação através de Ant, usando o destino bind do build.xml. A Figura 2 mostra a saída que você deve ver ao executar esse destino, supondo que você já tenha executado os destinos compile e bindgen . (Você também pode executar todos os três destinos em seqüência, listando-os em ordem na linha de comando: ant compile bindgen bind.)
Figura 2. Tarefa de Construção Antbind
Usando JiBX no Tempo de Execução
A Listagem 3 mostra um documento de teste simples que corresponde ao esquema gerado, incluído no download do código do tutorial como data.xml:
Listagem 3. Documento de Teste de Ligação Padrão
<order orderNumber="12345678" orderDate="2008-10-18" shipDate="2008-10-22"
xmlns="http://jibx.org/starter">
<customer customerNumber="5678">
<firstName>John</firstName>
<lastName>Smith</lastName>
</customer>
<billTo>
<street1>12345 Happy Lane</street1>
<city>Plunk</city>
<state>WA</state>
<postCode>98059</postCode>
<country>USA</country>
</billTo>
<shipping>PRIORITY_MAIL</shipping>
<shipTo>
<street1>333 River Avenue</street1>
<city>Kirkland</city>
<state>WA</state>
<postCode>98034</postCode>
<country>USA</country>
</shipTo>
<item quantity="1" price="5.99">
<id>AC4983498512</id>
<description>Left-handed widget</description>
</item>
<item quantity="2" price="9.50">
<id>IW2349050499</id>
<description>Right-handed widget</description>
</item>
<item quantity="1" price="8.95">
<id>RC3000488209</id>
<description>High-speed MP3 rewinder</description>
</item>
</order> |
O pacote de download também inclui um programa de teste simples, mostrado aqui como Listagem 4, que demonstra o uso de JiBX para desserializar e serializar documentos. (Serializar é o processo de gerar uma representação XML para um objeto em memória, potencialmente incluindo objetos vinculados a partir do objeto original. Desserializar é o processo inverso de serializar, construir um objeto (e potencialmente um gráfico de objetos vinculados) em memória de uma representação XML.) O destino Ant run executa esse programa de teste, usando o documento Listagem 3 como entrada e gravando a cópia serializada do documento em um arquivo denominado out.xml.
Listagem 4. Programa de Teste
public class Test
{
/**
* Desserializar o documento de amostra de um arquivo, computar e configurar total do pedido, em seguida,
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- Erro XML: A linha anterior não é maior do que o máximo de 90 caracteres ---------|
* serializá-lo novamente em outro arquivo.
*
* @param args
*/
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Usage: java -cp ... " +
"org.jibx.starter.Test in-file out-file");
System.exit(0);
}
try {
// desserializar informações do cliente a partir do arquivo
IBindingFactory bfact = BindingDirectory.getFactory(Order.class);
IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
FileInputStream in = new FileInputStream(args[0]);
Order order = (Order)uctx.unmarshalDocument(in, null);
// computar o valor total do pedido
float total = 0.0f;
for (Iterator<Item> iter = order.getItems().iterator(); iter.hasNext();) {
Item item = iter.next();
total += item.getPrice() * item.getQuantity();
}
order.setTotal(new Float(total));
// serializar objeto novamente para o arquivo (com bom deslocamento, como UTF-8)
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- Erro XML: A linha anterior não é maior do que o máximo de 90 caracteres ---------|
IMarshallingContext mctx = bfact.createMarshallingContext();
mctx.setIndent(2);
FileOutputStream out = new FileOutputStream(args[1]);
mctx.setOutput(out, null);
mctx.marshalDocument(order);
System.out.println("Processed order with " + order.getItems().size() +
" items and total value " + total);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(1);
} catch (JiBXException e) {
e.printStackTrace();
System.exit(1);
}
}
} |
A Figura 3 mostra a saída que você deve ver ao executar o destino run :
Figura 3. Tarefa de Construção Ant run
Você pode inspecionar o arquivo out.xml gerado para ver como ele corresponde à entrada original mostrada na Listagem 3. Além da declaração de namespace, da ordem dos atributos e do atributo total incluído na saída (computador e configurados pelo programa de teste), os dois documentos devem ser idênticos. Isso nem sempre será o caso! JiBX, como a maioria dos formulários de ligação de dados, funciona somente com dados "significativos" no documento, o que significa que esses valores que estão sendo usados por seu aplicativo. Partes não significativas do documento (como espaço em branco em uma tag de início e de finalização, texto entre elementos e comentários) são perdidas quando quando você desserializa um documento. Parte da razão dos documentos de entrada e saída serem tão semelhantes nesse caso é que o código da Listagem 4 configura o formato de saída para usar deslocamento de dois espaços por nível de aninhamento de elemento, correspondendo ao documento de entrada.
Observadores mais detalhistas observarão uma diferença entre a entrada e saída que parece significativa, na parte da lista de itens do documento de saída, mostrada na Listagem 5:
Listagem 5. Lista de Itens do Documento de Saída
<item quantity="1" price="5.99">
<id>AC4983498512</id>
<description>Left-handed widget</description>
</item>
<item quantity="2" price="9.5">
<id>IW2349050499</id>
<description>Right-handed widget</description>
</item>
<item quantity="1" price="8.95">
<id>RC3000488209</id>
<description>High-speed MP3 rewinder</description>
</item>
|
Se você comparar a linha mostrada em negrito na Listagem 5 com a linha correspondente no documento original da Listagem 3 , você pode ver que o preço foi alterado de 9.50 para 9.5, com a remoção do zero à direita. Isso não é um erro, no entanto. A representação usada para o valor do preço é um float e em termos de esquema Java e XML, zeros à esquerda antes do ponto decimal e zeros à direita após o ponto decimal não são significativos para um float.
|