вівторок, 27 листопада 2018 р.

JAXB: розпаковування та генерування XML документів

JAXB (Java Architecture for XML Binding) дозволяє швидко розпакувати (unmarshall) xml файл у об’єкти та згенерувати/запакувати (marshall) xml із об’єкту. JAXB використовується, зокрема, при розробці RESTtful Веб-сервісів, коли необхідно швидко згенерувати xml у якості відповіді клієнту або розпакувати із http запиту.
Для прикладу є простий XML документ:
<?xml version="1.0" encoding="UTF-8"?>
<Data>
 <id>1</id>
 <name>Галина Мер</name>
 <mobile>+380970000001</mobile>
</Data>

Для того, щоб розпакувати наш xml об'єкт нам потрібен клас із відповідною анотацією.

package ua.volodimirg;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Data")
public class Data {
 @XmlElement(name = "id")
 private int id;
 @XmlElement(name = "name")
 private String name;
 @XmlElement(name = "mobile")
 private String mobile;
 
 @Override
 public String toString() {
  return "Data [id=" + id + ", name=" + name + ", mobile=" + mobile + "]";
 }
}

Параметр name необхідно вказувати, якщо назви елементів xml відрізняються від назви полів класу. В нашому випадку анотацію біля полів @XmlElement(name = "") можна упустити, якщо реалізувати геттер та сеттер методи. В такому вигляді, без геттер і сеттер методів, якщо цю анотацію опустити, то розпакування не відбудеться.

Метод toString() заміщено для наглядності, щоб перевірити чи ми дійсно прочитали xml елементи у поля класу.

Наступний клас дозволяє нам розпакувати нам наш XML у екземпляр класу Data
package ua.volodimirg;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class TestJAXB {

 public static void main(String[] args) {
  try {

   JAXBContext jaxb = JAXBContext.newInstance(Data.class);
   Unmarshaller unmarshaller = jaxb.createUnmarshaller();
   File xmlFile = new File("D:\\testjaxb.xml");
   Data data = (Data) unmarshaller.unmarshal(xmlFile);
   System.out.println(data);
   
  } catch (JAXBException e) {
   e.printStackTrace();
  }
  

 }

}

Результат виконання:
Data [id=1, name=Галина Мер, mobile=+380970000001]

Генерування XML (marshalling)
Оскільки ми маємо об’єкт data можемо зворотно згенерувати XML . Для цього додаємо наступний код:
 //створити пакувальника
 Marshaller marshaller = jaxb.createMarshaller();
 //запакувати об'єкт в читабельній для людей формі,
 // тобто відформатований по рядках
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
 // запакувати об'єкт data в XML та вивести на консоль
 marshaller.marshal(data, System.out);

Замість System.out можна написати new File(“D:\\mytest.xml”) і зберегти таким чином згенерований xml на диску.

Генерування xml із групи об’єктів

Допустимо необхідно згенерувати xml, який містить декілька об’єктів Data в одному xml файлі. Для цього необхідно створити об'єкт, який би згрупував би наші об'єкти тобто помістити їх у колекцію, наприклад, у List.

Перепишемо наш клас Data згенерувавши геттер і сеттер методи. Це дасть можливість нам створити декілька різних екземплярів Data.

package ua.volodimirg;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Data")
public class Data {

 private int id;
 private String name;
 private String mobile;
 
 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 getMobile() {
  return mobile;
 }
 public void setMobile(String mobile) {
  this.mobile = mobile;
 }

 @Override
 public String toString() {
  return "Data [id=" + id + ", name=" + name + ", mobile=" + mobile + "]";
 }
}


Створимо клас DataArray:
package ua.volodimirg;


import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="DataArray")
public class DataArray {
 List dataArray=null;

 public List getDataArray() {
  return dataArray;
 }

 public void setDataArray(List dataArray) {
  this.dataArray = dataArray;
 }

 @Override
 public String toString() {
  return "DataArray [dataArray=" + dataArray + "]";
 }
 
}

Генеруємо xml (TestJAXB2.java)
package ua.volodimirg;


import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class TestJAXB2 {

 public static void main(String[] args) {
 
  //створюємо об'єкти data
  Data data1=new Data();
  data1.setId(1);
  data1.setMobile("+380970000001");;
  data1.setName("Галина Мер");
  Data data2=new Data();
  data2.setId(2);
  data2.setMobile("+380950000002");;
  data2.setName("Петро Гак");
  //створюємо екземпляр dataArray
  DataArray dataArray=new DataArray();
  dataArray.setDataArray(new ArrayList());
  //додаємо об'єкти у список
  dataArray.getDataArray().add(data1);
  dataArray.getDataArray().add(data2);
  
  //генеруємо xml
  JAXBContext jaxb;
  try {
   jaxb = JAXBContext.newInstance(DataArray.class);
   Marshaller marshaller = jaxb.createMarshaller();
   marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
   marshaller.marshal(dataArray, System.out);
  } catch (JAXBException e) {
   e.printStackTrace();
  }

  
 }

}

Результат:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DataArray>
    <dataArray>
        <id>1</id>
        <mobile>+380970000001</mobile>
        <name>Галина Мер</name>
    </dataArray>
    <dataArray>
        <id>2</id>
        <mobile>+380950000002</mobile>
        <name>Петро Гак</name>
    </dataArray>
</DataArray>

Джерела:
https://keyholesoftware.com/2014/07/21/jaxb-part-1/
https://keyholesoftware.com/2014/08/25/jaxb-part-2/
https://howtodoinjava.com/jaxb/jaxb-exmaple-marshalling-and-unmarshalling-list-or-set-of-objects/
https://www.mysoftkey.com/java/jaxb-nested-list-of-java-object-example/

Немає коментарів:

Дописати коментар