Рубрики
Без рубрики

Пример JAXB привет, мир

Эта статья будет посвящена JAXB 3, EclipseLink Moxy JAXB RI и Java 11. Сортировка и распаковка XML для преобразования объектов Java в XML и из XML.

Jakarta XML Binding (JAXB; ранее архитектура Java для привязки XML) – это платформа привязки XML для преобразования объектов Java в XML и из XML.

  1. Сортировка XML – Преобразование объектов Java в XML.
  2. Распаковка 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).

  1. С появлением веб-сервисов на основе XML JAXB стал частью Java 6.
  2. Появление веб-служб на основе JSON или веб-структуры REST заставляет разработчиков переходить с XML на JSON и REST.
  3. JAXB все еще является частью Java 7 и Java 8.
  4. Java 9 устарела для модулей Java EE, включая JAXB javax.xml . * , и отметьте его устаревшим для удаления , что означает, что JAXB все еще является частью Java 9, и будущий выпуск Java удалит их.
  5. ДЖАКСБ javax.xml . * все еще являются устаревшими и являются частью Java 10.
  6. JAXB по-прежнему является частью Java 9 и Java 10, но отключен или не включен в путь к модулю по умолчанию; Однако мы все еще можем явно включить его через --add-modules (Не рекомендуется). Рекомендуемое решение – добавить отдельный API JAXB и реализацию JAXB.
  7. С появлением микросервисов разработчики хотят иметь небольшую и легкую среду выполнения Java.
  8. Java 11 удалила JAXB javax.xml . * полностью. Теперь нам нужно добавить отдельный API JAXB и реализацию JAXB для использования функций JAXB.
  9. Oracle представила Java EE в Eclipse Foundation, а Java EE переименована в Jakarta EE из-за торговой марки “Java”. ДЖАКСБ javax.xml . * также переупаковывать в jakarta.xml . * начиная с версии 3.0.

Дальнейшее Чтение

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 включают в себя следующие вещи:

  1. А Company.class содержит список Staff.class , с аннотациями JAXB для преобразования XML.
  2. Преобразование Java 8 Дата в зоне используя @xmljavatypeадаптер .
  3. 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")
  List list;

  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-файл в компактном режиме.

  
  Banana9.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. Рекомендации

Оригинал: “https://mkyong.com/java/jaxb-hello-world-example/”