Jakarta XML Binding (JAXB; ранее архитектура Java для привязки XML) – это платформа привязки XML для преобразования объектов Java в XML и из XML.
- Сортировка XML – Преобразование объектов Java в XML.
- Распаковка XML – Преобразование XML обратно в объекты Java.
Примечание Эта статья будет посвящена Java 11 , JAXB 3 и EclipseLink moxy JAXB RI .
Содержание
- 1. JAXB на Java 6, 7, 8, Java 9, 10, 11 и за
- 2. Java 11 и JAXB RI зависимости
- 2.1 Эклипслинк Мокси
- 2.1 Привязка XML в Джакарте
- 3. Пример JAXB привет, мир
- 3.1 Сортировка XML JAXB – Преобразование объектов Java в XML
- 3.2 Распаковка XML JAXB – Преобразование XML в объекты Java
- 4. Что такое @xmlaccessortype(xmlaccesstype. ПОЛЕ)
- 5. Разница между javax.xml . * и jakarta.xml . *
- 5.1 Java EE, javax.xml . * для JAXB версии 2
- 5.2 Джакарта EE, jakarta.xml . * для JAXB версии 3
- 6. Примеры JAXB, список, адаптер для времени и CDATA
- 6.1 Класс домена JAXB
- 6.2 Адаптер JAXB
- 6.3 JAXB и CDATA
- 6.4 Запустить JAXB
- 7. Советы JAXB
- 7.1 XML красивая печать
- 7.2 Измените кодировку XML
- 7.3 Удалите XML-декларацию
- 7.4 Измените порядок полей
- 7.5 Скрыть указанное поле для сопоставления
- 7.6 Реализация JAXB-API не найдена
- 8. Скачать Исходный Код
- 9. Рекомендации
1. JAXB на Java 6, 7, 8, Java 9, 10, 11 и за
Ниже приведена краткая история привязки XML в Джакарте (JAXB; ранее архитектура Java для привязки XML).
- С появлением веб-сервисов на основе XML JAXB стал частью Java 6.
- Появление веб-служб на основе JSON или веб-структуры REST заставляет разработчиков переходить с XML на JSON и REST.
- JAXB все еще является частью Java 7 и Java 8.
- Java 9 устарела для модулей Java EE, включая JAXB
javax.xml . *
, и отметьте его устаревшим для удаления , что означает, что JAXB все еще является частью Java 9, и будущий выпуск Java удалит их. - ДЖАКСБ
javax.xml . *
все еще являются устаревшими и являются частью Java 10. - JAXB по-прежнему является частью Java 9 и Java 10, но отключен или не включен в путь к модулю по умолчанию; Однако мы все еще можем явно включить его через
--add-modules
(Не рекомендуется). Рекомендуемое решение – добавить отдельный API JAXB и реализацию JAXB. - С появлением микросервисов разработчики хотят иметь небольшую и легкую среду выполнения Java.
- Java 11 удалила JAXB
javax.xml . *
полностью. Теперь нам нужно добавить отдельный API JAXB и реализацию JAXB для использования функций JAXB. - Oracle представила Java EE в Eclipse Foundation, а Java EE переименована в Jakarta EE из-за торговой марки “Java”. ДЖАКСБ
javax.xml . *
также переупаковывать вjakarta.xml . *
начиная с версии 3.0.
Дальнейшее Чтение
- Java 11– JEP 320: Удалите модули Java EE и CORBA
- Привязка XML Википедии – Джакарты
- Википедия – Джакарта EE
2. Java 11 и JAXB RI зависимости
JAXB – это спецификация JSR-222 , и ниже приведены две распространенные реализации JAXB:
2.1 Эклипслинк Мокси
Ниже приведена зависимость Maven EclipseLink от MOXY.
jakarta.xml.bind jakarta.xml.bind-api 3.0.0 org.eclipse.persistence org.eclipse.persistence.moxy 3.0.0
2.1 Привязка XML в Джакарте
Ниже приведена привязка Maven Jakarta XML зависимость.
jakarta.xml.bind jakarta.xml.bind-api 3.0.0 com.sun.xml.bind jaxb-impl 3.0.0 runtime
Если мы все еще предпочитаем старые пакеты JAXB javax.xml . *
, придерживайтесь версии JAXB 2.x.
jakarta.xml.bind jakarta.xml.bind-api 2.3.3 com.sun.xml.bind jaxb-ri 2.3.3
Примечание
- В Java 6, 7 и 8 JAXB является частью JDK.
- В Java 9, 10, 11 и более поздних версиях нам необходимо добавить отдельный JAXB API и JAXB RI или библиотеки реализации для использования функций JAXB.
3. Пример JAXB привет, мир
Класс с аннотациями JAXB.
package com.mkyong.xml.jaxb.model; import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement // order of the fields in XML // @XmlType(propOrder = {"price", "name"}) @XmlAccessorType(XmlAccessType.FIELD) public class Fruit { @XmlAttribute int id; @XmlElement(name = "n") String name; String price; // getter, setter and toString... }
3.1 Сортировка XML JAXB – Преобразование объектов Java в XML
Приведенный ниже пример JAXB для маршалинга XML преобразует объекты Java в XML.
package com.mkyong.xml.jaxb; import com.mkyong.xml.jaxb.model.Fruit; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.Marshaller; import java.io.File; public class JaxbExampleFruit1 { public static void main(String[] args) { JAXBContext jaxbContext = null; try { // Normal JAXB RI //jaxbContext = JAXBContext.newInstance(Fruit.class); // EclipseLink MOXy needs jaxb.properties at the same package with Fruit.class // Alternative, I prefer define this via eclipse JAXBContextFactory manually. jaxbContext = org.eclipse.persistence.jaxb.JAXBContextFactory .createContext(new Class[]{Fruit.class}, null); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); // output pretty printed jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); Fruit o = new Fruit(); o.setId(1); o.setName("Banana"); o.setPrice("9.99"); // output to a xml file jaxbMarshaller.marshal(o, new File("C:\\test\\fruit.xml")); // output to console // jaxbMarshaller.marshal(o, System.out); } catch (JAXBException e) { e.printStackTrace(); } } }
Выход
Banana 9.99
3.2 Распаковка XML JAXB – Преобразование XML в объекты Java
Приведенный ниже пример JAXB для распаковки XML преобразует XML обратно в объекты Java.
package com.mkyong.xml.jaxb; import com.mkyong.xml.jaxb.model.Fruit; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.Unmarshaller; import java.io.File; public class JaxbExampleFruit2 { public static void main(String[] args) { JAXBContext jaxbContext = null; try { // Normal JAXB RI //jaxbContext = JAXBContext.newInstance(Fruit.class); // EclipseLink MOXy needs jaxb.properties at the same package with Fruit.class // Alternative, I prefer define this via eclipse JAXBContextFactory manually. jaxbContext = org.eclipse.persistence.jaxb.JAXBContextFactory .createContext(new Class[]{Fruit.class}, null); File file = new File("C:\\test\\fruit.xml"); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); Fruit o = (Fruit) jaxbUnmarshaller.unmarshal(file); System.out.println(o); } catch (JAXBException e) { e.printStackTrace(); } } }
Выход
Fruit{id=1, name='Banana', price='9.99'}
4. Что такое @xmlaccessortype(xmlaccesstype. ПОЛЕ)
По умолчанию реализация JAXB будет использовать пару геттер/сеттер, общедоступные поля и аннотированные непубличные поля JAXB для преобразования XML.
4.1 Еще раз просмотрите класс Fruit
, если мы закомментируем @xmlaccessortype(xmlaccesstype. ПОЛЕ)
, и повторно запустите вышеупомянутую программу JAXB.
@XmlRootElement //@XmlAccessorType(XmlAccessType.FIELD) public class Fruit { @XmlAttribute int id; @XmlElement(name = "n") String name; String price; 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; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } @Override public String toString() { return "Fruit{" + "id=" + id + ", name='" + name + '\'' + ", price='" + price + '\'' + '}'; }
4.2 Мы получим следующее Класс имеет два свойства с одинаковым именем
сообщение об ошибке.
Class has two properties of the same name "id" this problem is related to the following location: at public int com.mkyong.xml.jaxb.model.Fruit.getId() at com.mkyong.xml.jaxb.model.Fruit this problem is related to the following location: at int com.mkyong.xml.jaxb.model.Fruit.id at com.mkyong.xml.jaxb.model.Fruit Class has two properties of the same name "name" this problem is related to the following location: at public java.lang.String com.mkyong.xml.jaxb.model.Fruit.getName() at com.mkyong.xml.jaxb.model.Fruit this problem is related to the following location: at java.lang.String com.mkyong.xml.jaxb.model.Fruit.name at com.mkyong.xml.jaxb.model.Fruit
JAXB рассмотрит Fruit.getId()
и Fruit.id
(потому что мы аннотировали @XmlAttribute
или @XmlElement
) как одно и то же свойство; Чтобы решить эту проблему, мы добавляем @xmlaccessortype(xmlaccesstype. ПОЛЕ)
на уроке сказать ДЖАКСБУ только брать Fruit.id
как собственность.
Примечание У EclipseLink Moxy JAXB нет вышеуказанной проблемы.
5. Разница между javax.xml . * и jakarta.xml . *
Фонд Eclipse провел ребрендинг Java EE javax.xml . *
в Джакарту EE jakarta.xml . *
.
Ниже приведены некоторые API-интерфейсы JAXB в версиях 2 и 3.
// Jakarta EE // @Since 3.0.0, rebrand to jakarta.xml import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.Marshaller; // Java EE // old APIs JAXB version 2.* import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller;
5.1 Java EE, javax.xml . * для JAXB версии 2
В JAXB версии 2 API-интерфейсы используют старый пакет Java EE javax.xml . *
.
javax.xml.bind jaxb-api 2.3.1 org.eclipse.persistence org.eclipse.persistence.moxy 2.7.8
5.2 Джакарта EE, jakarta.xml . * для JAXB версии 3
В JAXB версии 3.x и выше API-интерфейсы переупаковываются в пакет Jakarta EE jakarta.xml . *
.
jakarta.xml.bind jakarta.xml.bind-api 3.0.0 org.eclipse.persistence org.eclipse.persistence.moxy 3.0.0
6. Примеры JAXB, список, адаптер для времени и CDATA
Приведенные ниже примеры JAXB включают в себя следующие вещи:
- А
Company.class
содержит списокStaff.class
, с аннотациями JAXB для преобразования XML. - Преобразование Java 8
Дата в зоне
используя@xmljavatypeадаптер
. - XML-ДАННЫЕ для специальных символов
@Xmldata
доступны только в EclipseLink Moxy JAXB RI.
6.1 Класс домена JAXB
Два класса домена с аннотациями JAXB.
package com.mkyong.xml.jaxb.model; import com.mkyong.xml.jaxb.adaptor.TimeZoneAdaptor; // @Since 3.0 import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.eclipse.persistence.oxm.annotations.XmlCDATA; // Java 8? //import com.sun.xml.internal.txw2.annotation.XmlCDATA; // jaxb 2 //import javax.xml.bind.annotation.*; import java.time.ZonedDateTime; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Staff { @XmlAttribute int id; String name; String Salary; @XmlCDATA String bio; @XmlJavaTypeAdapter(TimeZoneAdaptor.class) ZonedDateTime joinDate; //getters, setters }
package com.mkyong.xml.jaxb.model; //import javax.xml.bind.annotation.*; // @Since 3.0.0 import jakarta.xml.bind.annotation.*; import java.util.List; @XmlRootElement @XmlType(propOrder = {"name", "list"}) @XmlAccessorType(XmlAccessType.FIELD) public class Company { @XmlElement(name = "staff") Listlist; String name; // getters, and setters }
6.2 Адаптер JAXB
Мы можем использовать @XmlJavaTypeAdapter
для преобразования Дата в зоне
(или других типов) до и из Строка
.
package com.mkyong.xml.jaxb.adaptor; // @Since 3.0.0 import jakarta.xml.bind.annotation.adapters.XmlAdapter; //import javax.xml.bind.annotation.adapters.XmlAdapter; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; public class TimeZoneAdaptor extends XmlAdapter{ DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; @Override public ZonedDateTime unmarshal(String v) throws Exception { ZonedDateTime parse = ZonedDateTime.parse(v, dateTimeFormatter); return parse; } @Override public String marshal(ZonedDateTime v) throws Exception { return dateTimeFormatter.format(v); } }
6.3 JAXB и CDATA
Для некоторых специальных символов в XML-документах, таких как <
и &
, нам нужны CDATA .
Мы выбираем EclipseLink Moxy JAXB RI, потому что есть встроенный @XMLCDATA
для автоматического переноса текста с CDATA
.
import org.eclipse.persistence.oxm.annotations.XmlCDATA; //... @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Staff { //... @XmlCDATA String bio;
6.4 Запустить JAXB
В приведенном ниже примере JAXB попробуйте преобразовать список объектов в XML-документ.
package com.mkyong.xml.jaxb; import com.mkyong.xml.jaxb.model.Company; import com.mkyong.xml.jaxb.model.Staff; // @Since 3.0.0, rebrand to jakarta.xml import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.Marshaller; // old APIs 2.3.*, //import javax.xml.bind.JAXBContext; //import javax.xml.bind.JAXBException; //import javax.xml.bind.Marshaller; import java.io.File; import java.time.ZonedDateTime; import java.util.Arrays; public class JaxbExample { public static void main(String[] args) { JAXBContext jaxbContext = null; try { //jaxbContext = JAXBContext.newInstance(Company.class); // EclipseLink MOXy needs jaxb.properties at the same package with Company.class or Staff.class // Alternative, I prefer define this via eclipse JAXBContextFactory manually. jaxbContext = org.eclipse.persistence.jaxb.JAXBContextFactory .createContext(new Class[] {Company.class}, null); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); // output pretty printed jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); //jaxbMarshaller.marshal(createCompanyObject(), new File("C:\\test\\company.xml")); jaxbMarshaller.marshal(createCompanyObject(), System.out); // XML Unmarshalling /*File file = new File("C:\\test\\company.xml"); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); Company o = (Company) jaxbUnmarshaller.unmarshal(file); System.out.println(o);*/ } catch (JAXBException e) { e.printStackTrace(); } } private static Company createCompanyObject() { Company comp = new Company(); comp.setName("ABCDEFG Enterprise"); Staff o1 = new Staff(); o1.setId(1); o1.setName("mkyong"); o1.setSalary("8000 & Bonus"); o1.setBio("support
"); o1.setJoinDate(ZonedDateTime.now().minusMonths(12)); Staff o2 = new Staff(); o2.setId(2); o2.setName("yflow"); o2.setSalary("9000"); o2.setBio("developer & database
"); o2.setJoinDate(ZonedDateTime.now().minusMonths(6)); comp.setList(Arrays.asList(o1, o2)); return comp; } }
Выход
ABCDEFG Enterprise mkyong 8000 & Bonus support]]> 2020-04-21T12:19:28.5450719+08:00 yflow 9000 developer & database]]> 2020-10-21T12:19:28.5450719+08:00
7. Советы JAXB
Некоторые часто задаваемые вопросы и советы JAXB.
7.1 XML красивая печать
По умолчанию JAXB выводит XML-файл в компактном режиме.
Banana 9.99
Чтобы JAXB выводил XML в режиме печати или форматирования, и мы можем установить свойство Маршаллер. JAXB_FORMATTED_OUTPUT
в истина
.
// default false jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Выход
Banana 9.99
7.2 Измените кодировку XML
Кодировка XML по умолчанию JAXB в кодировка="UTF 8"
, и мы можем настроить указанную кодировку XML с помощью свойства Маршаллера. КОДИРОВАНИЕ JAXB_ENCODING
.
// change XML encoding jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "ISO-8859-1");
Выход
7.3 Удалите XML-декларацию
Установите свойство Маршаллер. JAXB_FRAGMENT
в true
, и он удалит начальное объявление XML.
// default false // remove jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
Выход
Banana 9.99
7.4 Измените порядок полей
Мы можем использовать @XMLType пропорциональщик
для изменения порядка полей, записанных в XML-документ.
Еще раз просмотрите класс Фрукты
.
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Fruit { @XmlAttribute int id; @XmlElement(name = "n") String name; String price; //... }
Выход
Banana 9.99
Мы можем использовать @XMLType пропорциональщик
для управления порядком полей; например, в приведенном ниже примере требуется сначала отобразить цену
.
package com.mkyong.xml.jaxb.model; import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlType; @XmlRootElement @XmlType(propOrder = {"price", "name"}) @XmlAccessorType(XmlAccessType.FIELD) public class Fruit { @XmlAttribute int id; @XmlElement(name = "n") String name; String price; //... }
Выход
9.99 Banana
7.5 Скрыть указанное поле для сопоставления
Мы можем использовать @XmlTransient
, чтобы скрыть или предотвратить преобразование определенного поля в XML.
import jakarta.xml.bind.annotation.XmlTransient; //... @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Fruit { @XmlAttribute int id; @XmlElement(name = "n") String name; // Prevents the mapping @XmlTransient String price;
Выход
Banana
7.6 Реализация JAXB-API не найдена
Нам нужно предоставить JAXB RI или реализацию, обратитесь к этой статье.
Связанные ошибки
- java.lang. NoClassDefFoundError: исключение javax/xml/привязка/jaxbex
- java.lang. Исключение ClassNotFoundException: com.sun.xml.привязка.v2.ContextFactory
8. Скачать Исходный Код
$клон git $клон git
$компакт-диск java-xml
$cd src/основной/java/com/mkyong/xml/jaxb$cd src/основной/java/com/mkyong/xml/jaxb/
9. Рекомендации
- Спецификация JAXB JSR-222
- Oracle – Введение в JAXB
- Википедия – Джакарта EE
- Привязка XML ВИкипедии – Джакарты
- Руководство пользователя JAXB
- Эклипслинк Мокси
- Архитектура Java для привязки XML (JAXB)
- Привязка XML Джакарты
- Java 11– JEP 320: Удалите модули Java EE и CORBA
- Примеры Java 8–ZonedDateTime
- Java 8 – Как преобразовать строку в LocalDate
- Исключение JAXBException: Реализация JAXB-API не найдена
- Стековый поток – Как сгенерировать блок CDATA с помощью JAXB?
- JAXB на Java 9, 10, 11 и более поздних версиях
Оригинал: “https://mkyong.com/java/jaxb-hello-world-example/”