03.04.2013

Связывание XML данных с помощью Castor.

В Java для связывания данных с их XML представлением существует несколько способов (например JAXB: использование JAXB, автоматизация JAXB маппинга). Хотелось бы рассказать про использование одного из них - Castor. Castor это фреймворк, обеспечивающий связывание Java объектов с их XML представлением или с представлением в реляционных базах данных. Использование JAXB подходит во многих случаях, но маппинг XML/Java с помощью Castor обеспечивает большую гибкость. Он позволяет использовать несколько режимов связывания - как простой, так и более сложные, в которых доступно множество возможностей для тонокой настройки формата связываемых данных. Итак, давайте посмотрим, какие это режимы, как и когда их лучше использовать, а также как упростить процесс связывания.
 
Простой способ, или intorspection mode.
 
Для того, чтобы начать использовать Castor, загрузите его последнюю версию и включите jar-библиотеки в ваш проект. Использовать 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