Ръководство за JAXB

1. Въведение

Това е уводна статия за JAXB (Java Architecture for XML Binding).

Първо ще покажем как да конвертираме Java обекти в XML и обратно, а след това ще се съсредоточим върху генерирането на Java класове от XML схема и обратно, като използваме приставката JAXB-2 Maven.

2. Общ преглед

JAXB предоставя бърз и удобен начин за маршалиране (записване) на Java обекти в XML и демаршал (четене) на XML в обекти. Той поддържа рамка за обвързване, която отразява XML елементи и атрибути в Java полета и свойства, използвайки Java анотации.

Приставката JAXB-2 Maven делегира по-голямата част от работата си на някой от двата предоставени от JDK инструмента XJC и Schemagen.

3. JAXB Анотации

JAXB използва Java анотации за увеличаване на генерираните класове с допълнителна информация. Добавянето на такива анотации към съществуващите Java класове ги подготвя за изпълнението на JAXB.

Нека първо създадем прост Java обект, за да илюстрираме маршалиране и демаркиране:

@XmlRootElement(name = "book") @XmlType(propOrder = { "id", "name", "date" }) public class Book { private Long id; private String name; private String author; private Date date; @XmlAttribute public void setId(Long id) { this.id = id; } @XmlElement(name = "title") public void setName(String name) { this.name = name; } @XmlTransient public void setAuthor(String author) { this.author = author; } // constructor, getters and setters }

Горният клас по-горе съдържа следните пояснения:

  • @XmlRootElement : Името на коренния XML елемент се извлича от името на класа и ние също можем да посочим името на основния елемент на XML, използвайки неговия атрибут name
  • @XmlType : дефинирайте реда, в който полетата се записват в XML файла
  • @XmlElement : дефинирайте действителното име на XML елемент, което ще се използва
  • @XmlAttribute : дефинирайте полето id се съпоставя като атрибут вместо елемент
  • @XmlTransient : анотирайте полета, които не искаме да бъдат включени в XML

За повече подробности относно анотацията на JAXB може да разгледате следната връзка.

4. Маршалиране - Преобразуване на Java обект в XML

Маршалингът предоставя на клиентско приложение възможност да преобразува изведено от JAXB дърво на обекти Java в XML данни. По подразбиране Marshaller използва UTF-8 кодиране при генериране на XML данни. След това ще генерираме XML файлове от Java обекти.

Нека създадем проста програма, използвайки JAXBContext, която осигурява абстракция за управление на информацията за обвързване XML / Java, необходима за изпълнението на рамковите операции на JAXB:

public void marshal() throws JAXBException, IOException { Book book = new Book(); book.setId(1L); book.setName("Book1"); book.setAuthor("Author1"); book.setDate(new Date()); JAXBContext context = JAXBContext.newInstance(Book.class); Marshaller mar= context.createMarshaller(); mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); mar.marshal(book, new File("./book.xml")); }

Класът javax.xml.bind.JAXBContext предоставя входна точка на клиента за JAXB API. По подразбиране JAXB не форматира XML документа. Това спестява място и предотвратява случайно пробел да бъде интерпретиран като значителен.

За да форматираме изхода на JAXB, ние просто задаваме свойството Marshaller.JAXB_FORMATTED_OUTPUT на true в Marshaller . Маршалският метод използва обект и изходен файл, където да съхранява генерирания XML като параметри.

Когато стартираме горния код, можем да проверим резултата в book.xml, за да проверим дали успешно преобразуваме Java обект в XML данни:

  Book1 2016-11-12T11:25:12.227+07:00 

5. Демаркиране - Преобразуване на XML в Java обект

Un-marshalling предоставя на клиентско приложение възможност за конвертиране на XML данни в Java обекти, получени от JAXB.

Нека използваме JAXB Unmarshaller, за да демаршираме book.xml обратно към Java обект:

public Book unmarshall() throws JAXBException, IOException { JAXBContext context = JAXBContext.newInstance(Book.class); return (Book) context.createUnmarshaller() .unmarshal(new FileReader("./book.xml")); }

Когато стартираме горния код, можем да проверим изхода на конзолата, за да проверим дали сме преобразували успешно XML данни в Java обект:

Book [id=1, name=Book1, author=null, date=Sat Nov 12 11:38:18 ICT 2016]

6. Сложни типове данни

Когато обработваме сложни типове данни, които може да не са директно достъпни в JAXB, можем да напишем адаптер, който да посочи на JAXB как да управлява определен тип.

Използвайки XmlAdapter на JAXB , ние можем да дефинираме персонализиран код, за да преобразуваме неприложим клас в нещо, с което JAXB може да се справи. В @XmlJavaTypeAdapter анотацията използва адаптер, който се простира на XmlAdapter класа за потребителски marshaling.

Нека създадем адаптер, за да посочим формат на дата при марширане:

public class DateAdapter extends XmlAdapter { private static final ThreadLocal dateFormat = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; @Override public Date unmarshal(String v) throws Exception { return dateFormat.get().parse(v); } @Override public String marshal(Date v) throws Exception { return dateFormat.get().format(v); } }

Използваме формат на дата „ гггг-ММ-дд HH: mm: ss “, за да преобразуваме Date в String при марширане и ThreadLocal, за да направим нашата DateFormat безопасна за нишки.

Нека приложим DateAdapter към нашата книга :

@XmlRootElement(name = "book") @XmlType(propOrder = { "id", "name", "date" }) public class Book { private Long id; private String name; private String author; private Date date; @XmlAttribute public void setId(Long id) { this.id = id; } @XmlTransient public void setAuthor(String author) { this.author = author; } @XmlElement(name = "title") public void setName(String name) { this.name = name; } @XmlJavaTypeAdapter(DateAdapter.class) public void setDate(Date date) { this.date = date; } }

Когато стартираме горния код, можем да проверим резултата в book.xml, за да проверим дали сме преобразували успешно нашия Java обект в XML, използвайки новия формат на датата „ гггг-ММ-дд ЧЧ: мм: сс “:

  Book1 2016-11-10 23:44:18final 

7. Приставка JAXB-2 Maven

Този плъгин използва Java API за XML Binding (JAXB), версия 2+, за генериране на Java класове от XML схеми (и по желание обвързващи файлове) или за създаване на XML схема от коментиран Java клас.

Имайте предвид, че има два основни подхода за изграждане на уеб услуги, Contract Last и Contract First . За повече подробности относно тези подходи може да разгледате следната връзка.

7.1. Генериране на Java клас от XSD

Приставката JAXB-2 Maven използва предоставения от JDK инструмент XJC, инструмент за компилация на JAXB Binding, който генерира Java класове от XSD (XML Schema Definition).

Нека създадем прост файл user.xsd и използваме приставката JAXB-2 Maven, за да генерираме Java класове от тази XSD схема:

Нека конфигурираме приставката JAXB-2 Maven:

 org.codehaus.mojo jaxb2-maven-plugin 2.3   xjc  xjc      src/main/resources/global.xjb   src/main/resources/user.xsd  ${basedir}/src/main/java false  

По подразбиране този плъгин намира XSD файлове в src / main / xsd . Можем да конфигурираме търсене на XSD, като променим съответно раздела за конфигуриране на този плъгин в pom.xml .

По подразбиране тези Java класове се генерират в папката target / generated-resources / jaxb . Можем да променим изходната директория, като добавим елемент outputDirectory към конфигурацията на приставката. Може да добавим и елемент clearOutputDir със стойност false, за да предотвратим изтриването на файловете в тази директория.

Може също да конфигурираме глобално свързване на JAXB, което заменя правилата за обвързване по подразбиране:

В global.xjb горе Замените на дата час вида на java.util.Calendar тип.

Когато изграждаме проекта, той генерира файлове с класове в папката src / main / java и пакета com.baeldung.jaxb.gen .

7.2. Генериране на XSD схема от Java

The same plugin uses the JDK-supplied tool Schemagen. This is a JAXB Binding compiler tool that can generate an XSD schema from Java classes. In order for a Java Class to be eligible for an XSD schema candidate, the class must be annotated with a @XmlType annotation.

We reuse the Java class files from the previous example. Let's configure the plugin:

 org.codehaus.mojo jaxb2-maven-plugin 2.3   schemagen  schemagen      src/main/java/com/baeldung/jaxb/gen  src/main/resources false   /jaxb/gen user user-gen.xsd    

By default, JAXB scans all the folders under src/main/java recursively for annotated JAXB classes. We may specify a different source folder for our JAXB annotated classes by adding a source element to the plug-in configuration.

Можем също така да регистрираме transformSchemas , постопроцесор, отговорен за именуването на XSD схемата. Той работи чрез съвпадение на пространството от имена с пространството от имена на @XmlType на вашия Java клас.

Когато изграждаме проекта, той генерира файл user-gen.xsd в директорията src / main / resources .

8. Заключение

В тази статия разгледахме уводни концепции за JAXB. За подробности можем да разгледаме началната страница на JAXB.

Можем да намерим изходния код за тази статия в GitHub.