Архитектура Java для привязки XML (JAXB) — это библиотека, которая помогает связывать схемы XML и представления Java. JAXB предоставляет вам механизм для преобразования объектов Java в XML и наоборот — демонтажа XML в объекты Java.
XML является отраслевым стандартом для определения содержания вашего сообщения. XML, наряду с Java, являются дополнительными технологиями для обмена данными через Интернет. Когда вы работаете с XML, вам нужен способ взять файл XML, а затем преобразовать его в некую структуру данных, которой ваша программа может манипулировать. Вам также необходимо сериализовать состояние ваших объектов Java в XML. JAXB — это одна библиотека, которая выполняет такие операции маршалинга и демаршаллинга.
В этой статье я расскажу о том, как маршалировать объекты Java в XML и наоборот, используя JAXB.
Использование JAXB для маршала Java-объектов в XML
Давайте рассмотрим сценарий, в котором нам нужно смоделировать продукт для интернет-магазина. Помимо полей, таких как идентификатор продукта, описание, URL-адрес изображения и цена, объект « Продукт» также состоит из объекта « Пользователь», который представляет пользователя, который добавляет продукт в магазин.
Наша цель состоит в том, чтобы упорядочить объект Product вместе с его составным объектом User в XML с помощью JAXB.
Мы можем начать с создания пользовательского POJO для моделирования пользователя.
User.java:
package guru.springframework.blog.domain;
public class User {
private Long id;
private String name;
private String email;
public User() {
}
public User(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
public Long getId() {
return id;
}
public User setId(Long id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public User setName(String name) {
this.name = name;
return this;
}
public String getEmail() {
return email;
}
public User setEmail(String email) {
this.email = email;
return this;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("User{");
sb.append("id=").append(id);
sb.append(", name='").append(name).append('\'');
sb.append(", email='").append(email).append('\'');
sb.append('}');
return sb.toString();
}
}
Пользователь — это простой POJO с полями id, name и email, а также соответствующими методами getter и setter.
Далее мы создадим продукт POJO. При создании этого POJO мы будем использовать аннотации, представленные в JAXB 2.0, чтобы управлять тем, как наш объект Product маршалируется в XML.
Примечание. Начиная с JDK 1.6, JAXB входит в комплект JDK. Поэтому вам не нужно добавлять какие-либо зависимости для него.
Код продукта POJO приведен ниже.
Product.java
package guru.springframework.blog.domain;
import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
@XmlRootElement(name = "product")
//@XmlAccessorType(XmlAccessType.FIELD)
public class Product {
@XmlAttribute(name = "id")
private String productId;
@XmlElement(name = "description")
private String description;
@XmlElement(name = "imageUrl")
private String imageUrl;
@XmlElement(name = "price")
private BigDecimal price;
@XmlElement(name = "createdBy")
private User createdBy;
public Product(){}
public Product(String productId, String description, String imageUrl,
BigDecimal price, User createdBy) {
this.productId = productId;
this.description = description;
this.imageUrl = imageUrl;
this.price = price;
this.createdBy = createdBy;
}
@Override
public String toString() {
return "Product{" +
"\n productId='" + productId + '\'' +
",\n description='" + description + '\'' +
",\n imageUrl='" + imageUrl + '\'' +
",\n price=" + price +
",\n createdBy=" + createdBy +"\n"+
'}';
}
}
В этом классе Product мы использовали несколько аннотаций JAXB. Они есть:
- @ XmlRootElement : эта аннотация используется в классе верхнего уровня для указания корневого элемента в документе XML. Имя атрибута в аннотацииявляется обязательным. Если не указан, имя класса используется в качестве корневого XML-элемента в документе.
- @ XmlAttribute : эта аннотация используется для указания атрибута корневого элемента.
- @ XmlElement : эта аннотация используется для свойств класса, которые будут вложенными элементами корневого элемента.
Продукт POJO теперь готов быть ранжированы в XML. Для этого напишем тестовый класс JUnit. Если вы новичок в JUnit, я предлагаю вам пройти серию модульного тестирования с помощью JUnit .
Тестовый класс:
ProductToXmlTest.java:
package guru.springframework.blog.marshal;
import guru.springframework.blog.domain.Product;
import guru.springframework.blog.domain.User;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.File;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
public class ProductToXmlTest {
private Product product;
@Before
public void setUp() {
long l = 10;
Long longId = new Long(l);
User user = new User(longId, "John", "john@springframework.guru");
product = new Product("PO1", "Spring Guru Mug", "https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_shirt-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg", new BigDecimal(18.95), user);
}
@After
public void tearDown() {
product = null;
}
@Test
public void testObjectToXml() throws JAXBException, FileNotFoundException {
JAXBContext jaxbContext = JAXBContext.newInstance(Product.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(product, new File("product.xml"));
marshaller.marshal(product, System.out);
}
}
В этом коде:
- Строка 19 — Строка 24: создает и инициализирует объект User и Product в методе setup ( ), помеченном как @ Before .
- Строка 33: JAXBContext . Метод newInstance ( ) получает JAXBContext для класса Product, который вы хотите упорядочить . JAXBContext предоставляет точку входа для API JAXB.
- Строка 34: Создает маршаллер через вызов к createMarshaller ( ) методом JAXBContext . В JAXB класс Marshaller управляет процессом маршаллинга объектов Java в XML-данные с помощью различных методов маршаллинга.
- Строка 35: Конфигурирует маршаллера . Истинное значение JAXB_FORMATTED_OUTPUT собственности инструктирует ИАС для генерации XML с правильным отступом.
- Строка 36: вызывает метод marshal ( ) в Marshaller с инициализированным объектом Product и файлом для записи XML.
- Строка 37: Выделение объекта в «стандартный» выходной поток.
При запуске класса ProductToXmlTest , продукт . XML- файл генерируется.
Использование JAXB для демонтажа XML в объекты Java
Для демаршаллинга XML с JAXB на объект Java необходимо создать Unmarshaller в JAXBContext и вызвать метод unmarshal ( ) . Этот метод принимает файл XML для демаршалирования.
Тестовый класс JUnit для демонтажа сгенерированного продукта . XML обратно к объектам Product и User это:
XmlToProductTest.java:
package guru.springframework.blog.unmarshal;
import guru.springframework.blog.domain.Product;
import guru.springframework.blog.domain.User;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
public class XmlToProductTest {
private Product product;
@Test
public void testXmlToObject() throws JAXBException, FileNotFoundException {
File file = new File("product.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Product.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
product = (Product) unmarshaller.unmarshal(file);
System.out.println(product);
}
}
В этом классе XmlToProductTest используется JAXBContext, инициализированный с помощью Product . Метод createUnmarsheller ( ) возвращает Unmarshaller . JAXB Unmarshaller управляет процессом демонтажа XML-данных в дерево объектов Java. Наконец, метод unmarshal ( ) демаршализирует объект File для продукта . XML в продукт POJO.
Обработка коллекций
Часто вам потребуется маршалировать объекты коллекции Java, такие как List , Set и Map to XML, а также демонтировать XML обратно в объекты коллекции.
Рассмотрим наше текущее приложение, где нам теперь нужно работать со списком продуктов. Чтобы смоделировать новое требование, давайте создадим класс Products .
Код класса продуктов :
Products.java:
package guru.springframework.blog.domain;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
@XmlRootElement(name = "products")
public class Products {
List<Product> products;
public List<Product> getProducts() {
return products;
}
@XmlElement(name = "product")
public void setProducts(List<Product> products) {
this.products = products;
}
public void add(Product product) {
if (this.products == null) {
this.products = new ArrayList<Product>();
}
this.products.add(product);
}
}
В этом продуктах класса, @ XmlRootElement аннотации определяют корневой элемент XML в качестве продукции. Этот класс имеет единственное свойство List с методами getter и setter. Метод add ( ) этого класса принимает объект Product и добавляет его в список .
Тестовый класс для преобразования списка продуктов в XML:
ProductToXmlListTest.java:
package guru.springframework.blog.marshal;
import guru.springframework.blog.domain.Product;
import guru.springframework.blog.domain.Products;
import guru.springframework.blog.domain.User;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
public class ProductToXmlListTest {
private Product product;
private Product product1;
@Before
public void setUp(){
long l = 10;
Long longId = new Long(l);
User user = new User(longId,"John","john@springframework.guru");
product = new Product("PO1", "Spring Guru Mug","https://springframework.guru/wp-content/uploads/2017/12/spring_framework_guru_mug-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg", new BigDecimal(18.95),user);
product1 = new Product("PO2", "Spring Guru Shirt","https://springframework.guru/wp-content/uploads/2017/12/spring_framework_guru_shirt-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg", new BigDecimal(20.00),user);
}
@After
public void tearDown(){
product = null;
}
@Test
public void testObjectToXml() throws JAXBException, FileNotFoundException {
Products products = new Products();
products.add(product);
products.add(product1);
JAXBContext jaxbContext = JAXBContext.newInstance(Products.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
marshaller.marshal(products, new File("products.xml"));
marshaller.marshal(products, System.out);
}
}
Резюме
В этом посте я рассмотрел вводные концепции JAXB. Ранее я написал пост о том , как использовать XML — схемы и JAXB для создания классов Java для веб — служб RESTful здесь .
JAXB также поставляется с инструментом компоновки JAXB Binding под названием schemagen. Вы можете использовать schemagen для генерации схемы XSD из классов Java.
Исходный код этого поста доступен на GitHub. Вы можете скачать его здесь .