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; @XmlRootElement 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; } @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 . |