Статьи

Использование JAXB для XML с Java

Архитектура 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

В этом классе 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

Использование 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.

Результат выполнения теста:
Тестовый вывод JAXB Unmarshalling

Обработка коллекций

Часто вам потребуется маршалировать объекты коллекции 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:

Результат выполнения теста:

Резюме

В этом посте я рассмотрел вводные концепции JAXB. Ранее я написал пост о том , как использовать XML — схемы и JAXB для создания классов Java для веб — служб RESTful здесь .

JAXB также поставляется с инструментом компоновки JAXB Binding под названием schemagen. Вы можете использовать schemagen для генерации схемы XSD из классов Java.

Исходный код этого поста доступен на GitHub. Вы можете скачать его здесь .