Total Pageviews

2018/03/08

[Java] Utilize JAXB to Read / Write XML

Scenario

The XML content looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <products>
      <product id="P01">
          <description>Sony Alpha 7 II</description>
          <price>1620</price>
          <createdBy>
              <email>albert@gmail.com</email>
              <id>1</id>
              <name>Albert</name>
          </createdBy>
      </product>
      <product id="P02">
          <description>Sony Alpha 7R II</description>
          <price>2585</price>
          <createdBy>
              <email>albert@gmail.com</email>
              <id>1</id>
              <name>Albert</name>
          </createdBy>
      </product>
  </products>



How-To
Create three POJOs:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  package test.albert.xml;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import javax.xml.bind.annotation.XmlElement;
  import javax.xml.bind.annotation.XmlRootElement;
  
  import lombok.ToString;
  
  @XmlRootElement(name = "products")
  @ToString
  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);
      }
      
  }

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  package test.albert.xml;
  
  import java.math.BigDecimal;
  
  import javax.xml.bind.annotation.XmlAttribute;
  import javax.xml.bind.annotation.XmlElement;
  import javax.xml.bind.annotation.XmlRootElement;
  
  import lombok.AllArgsConstructor;
  import lombok.NoArgsConstructor;
  import lombok.ToString;
  
  /**
   * @XmlRootElement: This annotation is used at the top level class to indicate
   *                  the root element in the XML document. The name attribute in
   *                  the annotation is optional. If not specified, the class name
   *                  is used as the root XML element in the document.
   * @XmlAttribute: This annotation is used to indicate the attribute of the root
   *                element.
   * @XmlElement: This annotation is used on the properties of the class that will
   *              be the sub-elements of the root element.
   *
   */
  @AllArgsConstructor
  @NoArgsConstructor
  @ToString
  @XmlRootElement(name = "product")
  public class Product {
  
      @XmlAttribute(name = "id")
      private String productId;
  
      @XmlElement(name = "description")
      private String description;
  
      @XmlElement(name = "price")
      private BigDecimal price;
  
      @XmlElement(name = "createdBy")
      private User createdBy;
  
  }


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
  package test.albert.xml;
  
  import lombok.AllArgsConstructor;
  import lombok.Data;
  import lombok.NoArgsConstructor;
  import lombok.ToString;
  
  @ToString
  @NoArgsConstructor
  @AllArgsConstructor
  @Data
  public class User {
      private Long id;
      private String name;
      private String email;
  }


Create a test case to implement XML marshalling and unmarshalling:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  package test.albert.xml;
  
  import java.io.File;
  import java.math.BigDecimal;
  
  import javax.xml.bind.JAXBContext;
  import javax.xml.bind.JAXBException;
  import javax.xml.bind.Marshaller;
  import javax.xml.bind.Unmarshaller;
  
  import org.junit.After;
  import org.junit.Before;
  import org.junit.Test;
  
  import lombok.extern.slf4j.Slf4j;
  
  @Slf4j
  public class JAXBTest {
  
      private Product sonayA7ii;
      private Product sonayA7Rii;
      private String xmlFile;
  
      @Before
      public void setUp() {
          User albert = new User(1L, "Albert", "albert@gmail.com");
          sonayA7ii = new Product("P01", "Sony Alpha 7 II", new BigDecimal(1620), albert);
          sonayA7Rii = new Product("P02", "Sony Alpha 7R II", new BigDecimal(2585), albert);
          xmlFile = "F:" + File.separator + "product.xml";
      }
  
      @Test
      public void testObjectToXml() throws JAXBException {
  
          Products products = new Products();
          products.add(sonayA7ii);
          products.add(sonayA7Rii);
  
          JAXBContext jaxbContext = JAXBContext.newInstance(Products.class);
          Marshaller marshaller = jaxbContext.createMarshaller();
          marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  
          marshaller.marshal(products, new File(xmlFile));
          marshaller.marshal(products, System.out);
      }
  
      @Test
      public void testXmlToObject() throws JAXBException {
          File file = new File(xmlFile);
          JAXBContext jaxbContext = JAXBContext.newInstance(Products.class);
          Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
          
          Products products = (Products) unmarshaller.unmarshal(file);
          log.debug(products.toString());
      }
  
      @After
      public void tearDown() {
          sonayA7ii = null;
          sonayA7Rii = null;
          xmlFile = "";
      }
  
  }
  



No comments: