JAXB — это 10-летняя технология Java, которая позволяет нам преобразовывать объект Java в документ XML (маршалинг) и обратно (демаршаллинг). Эта технология основана на методах установки и получения и, на мой взгляд, нарушает ключевые принципы объектно-ориентированного программирования, превращая объекты в пассивные структуры данных . Я бы порекомендовал вам вместо этого использовать Xembly для маршалинга объектов Java в документы XML.
Так работает JAXB. Скажем, у вас есть класс Book который необходимо преобразовать в документ XML. Вы должны создать геттеры и аннотировать их:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElementpublic class Book { private final String isbn; private final String title; public Book(final String isbn, final String title) { this.isbn = isbn; this.title = title; } @XmlElement public String getIsbn() { return this.isbn; } @XmlElement public String getTitle() { return this.title; }} |
Затем вы создаете маршаллер и просите его преобразовать экземпляр класса Book в XML:
|
1
2
3
4
|
final Book book = new Book("0132350882", "Clean Code");final JAXBContext context = JAXBContext.newInstance(Book.class);final Marshaller marshaller = jaxbContext.createMarshaller();marshaller.marshal(book, System.out); |
Вы должны ожидать что-то вроде этого в выводе:
|
1
2
3
4
5
|
<?xml version="1.0"?><book> <isbn>0132350882</isbn> <title>Clean Code</title></book> |
Так что с этим не так? Практически то же самое, что не так с объектно-реляционным отображением, которое объясняется в ORM Is Offensive Anti-Pattern . JAXB рассматривает объект как пакет данных, извлекает данные и преобразует их в XML так, как хочет JAXB. Объект не контролирует этот процесс. Поэтому объект больше не является объектом , а скорее пассивным пакетом данных.
Идеальным подходом было бы изменить дизайн нашего класса Book следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
|
public class Book { private final String isbn; private final String title; public Book(final String isbn, final String title) { this.isbn = isbn; this.title = title; } public String toXML() { // create XML document and return }} |
Однако есть несколько проблем с этим подходом. Прежде всего, существует массовое дублирование кода. Создание документа XML — довольно многословный процесс в Java. Если бы каждый класс должен был повторно реализовать его в своем toXML() , у нас была бы большая проблема с дублирующимся кодом.
Вторая проблема заключается в том, что мы не знаем точно, в какой тип упаковки должен быть доставлен наш XML-документ. Это может быть String или InputStream или, может быть, экземпляр org.w3c.dom.Document . Создание многих toXML() в каждом объекте определенно было бы катастрофой.
Xembly предоставляет решение. Как я упоминал ранее , это обязательный язык для XML-конструкций и манипуляций. Вот как мы можем реализовать наш объект Book с помощью Xembly:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
import org.xembly.Directive;public class Book { private final String isbn; private final String title; public Book(final String isbn, final String title) { this.isbn = isbn; this.title = title; } public Iterable<Directive> toXembly() { return new Directives() .add("book") .add("isbn").set(this.isbn).up() .add("title").set(this.title).up() .up(); }} |
Теперь, чтобы построить XML-документ, мы должны использовать этот код вне объекта:
|
1
2
|
final Book book = new Book("0132350882", "Clean Code");final String xml = new Xembler(book.toXembly()).xml(); |
Этот класс Xembler преобразует директивы Xembly в документ XML.
Прелесть этого решения в том, что внутренние объекты объекта не открываются через геттеры, а объект полностью отвечает за процесс маршалинга XML. Кроме того, сложность этих директив может быть очень высокой — намного выше, чем довольно громоздкие аннотации JAXB.
- Xembly — это проект с открытым исходным кодом, поэтому не стесняйтесь отправлять свои вопросы или исправления в Github .
| Ссылка: | JAXB делает это неправильно; Попробуйте Xembly от нашего партнера JCG Егора Бугаенко в блоге About Programming . |