Связывание XML данных с помощью Castor.
public class SimpleClass { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Вот все, что необходимо для преобразования Java объекта в XML и обратно:
//create a simple object SimpleClass simpleClass = new SimpleClass(); simpleClass.setId(5); simpleClass.setName("simple class"); StringWriter writer = new StringWriter(); // Marshal the simple object Marshaller.marshal(simpleClass, writer); // Result string (XML) System.out.println("XML: " + writer.toString() + '\n'); StringReader reader = new StringReader(writer.toString()); // Unmarshal the simple object SimpleClass resultObject = (SimpleClass) Unmarshaller.unmarshal( SimpleClass.class, reader);
Сериализация существующего класса происходит без какого-либо описания или аннотаций, Castor самостоятельно принимает решение, в соответствии с соглашениями, о том, какой в данном случае должен быть формат выходных данных. Вот такой XML мы увидим на выходе:
<?xml version="1.0" encoding="UTF-8"?> <simple-class id="5"> <name>simple class</name> </simple-class>
Просто, но зачастую этого не достаточно - нужен строго заданный формат XML.
Использование дескрипторов классов, или descriptor mode.
Один из вариантов тонкой настройки формата данных - использование дескрипторов классов. Дескриптор класса это также Java класс, в котором описывается формат XML данных и каким образом связывать этот формат с классом. Такой вариант подходит в том случае, когда есть структура данных в виде XML, а классов еще нет. На основе этой структуры можно создать классы и их дескрипторы, которые будут использоваться для связывания. Здесь самое время привести пример, как можно автоматизировать маппинг. Итак, предположим у вас есть XML схема документа (XSD) или даже просто пример XML файла. А вам нужно создать соответствующую структуру Java классов и связать ее с XML. Для примера создадим такой XML:
<?xml version="1.0" encoding="UTF-8"?> <test-root id="100"> <some-element> <id>0</id> <name>Castor</name> <value1>4.5</value1> <value2>false</value2> </some-element> <object-type> <id>1</id> <description>Test Object</description> </object-type> <collection> <obj> <name>object 1</name> </obj> <obj> <name>object 2</name> </obj> </collection> </test-root>
Это все что у нас пока есть, но на основе этого документа можно автоматически создать схему. Для этого используем утилиту trang:
$ java -jar ./trang.jar ./example.xml ./schema.xsd
Вот как выглядит наша схема:
Обратите внимание, что на основе примера XML, trang создает полную схему, с указанием типов данных, "предположив" какие типы нам требуются, на основании заполненного примера XML. Так или иначе, схема у нас есть, теперь с помощью Castor Code Generator можно создать структуру классов с дескрипторами, которые разумеется потом можно изменить для более тонкой настройки (на сайте проекта Castor конечно же можно найти детальное описание этого). Создаем классы:
$ java org.exolab.castor.builder.SourceGeneratorMain -i schema.xsd -package com.blogspot.alexeydl
Для того, чтобы воспользоваться способом показанным выше, необходимо поместить в текущую директорию все классы из библиотек Castor. Кроме того понадобится Apache Commons Logging. Здесь можно скачать все в одном архиве. В итоге у нас есть структура классов, соответствующих схеме, для каждого класса есть класс-дескриптор и маршалинг/демаршалинг теперь делается таким образом (методы unmarshal и marshal теперь находятся непосредственно в созданном классе, в данном случае TestRoot.java):
//umarshal XML FileReader reader = new FileReader(INPUT_PATH); //result object TestRoot testRoot = TestRoot.unmarshal(reader); //marshal object StringWriter writer = new StringWriter(); testRoot.marshal(writer); //result string (XML) System.out.println("XML: " + writer.toString());
Использование такого способа выглядит достаточно просто, хотя дескрипторы и созданные классы выглядят достаточно громоздко. Но теперь с помощью изменения дескрипторов можно настроить формат XML данных так, как это необходимо. Полные исходники этого и всех других примеров можно найти ниже.
Использования файлов маппинга - mapping mode.
Третий способ создания маппинга - использования XML файлов для Castor, в которых будет описываться каким образом Java класс связывается с XML представлением. Также как и в предыдущем случае это позволяет очень гибко настроить формат данных, при этом - можно использовать уже существующие классы без каких-либо изменений. Никаких классов-дескрипторов не нужно, нужны только сами Java классы, составляющие структуру данных и файл/файлы описания маппинга. Кроме того, что XML файлы описания можно создать вручную, есть возможность сгенерировать их автоматически. Для того, чтобы это сделать нужно:
1. Скомпилировать классы для которых нужно создать описание:
$ javac ./com/blogspot/alexeydl/TestRoot.java
2. Создать XML описание командой:
$ java org.exolab.castor.tools.MappingTool -i com.blogspot.alexeydl.TestRoot -o mapping.xml
Разумеется, созданные файлы маппинга представляют собой своего рода шаблон, который с большой вероятностью нужно будет дорабатывать вручную.
Кроме исходников в архиве - файл маппинга, схема и сам XML, приведенный выше. В пакете com.blogspot.alexeydl - структура автоматически созданных по XML схеме классов. В пакете com.blogspot.alexeydl.descriptors - созданные автоматически дескрипторы классов. В пакете com.blogspot.alexeydl.test - тесты для каждого из трех описанных режимов маппинга.
Теги: xml java
comments powered by Disqus