JABX(Java Architecture for XML Binding)

 

https://www.vogella.com/tutorials/JAXB/article.html

JABX(Java Architecture for XML Binding)

 

This tutorial explains how to use JABX(Java Architecture for XML Binding) to parse XML documents to Java objects and vice versa.

1. Introduction into JAXB

1.1. What is JAXB?

Java Architecture for XML Binding (JAXB) is a standard that defines an API for reading and writing Java objects to and from XML documents. It applies a lot of defaults, thus making reading and writing of XML via Java relatively easy.

JAXB uses annotations in Java classes to add the necessary metadata for XML conversion. The following table gives an overview of the important annotations, their usage is demonstrated in the following examples.

Table 1. JAXB annotations
AnnotationDescription

@XmlRootElement(namespace = "namespace")

Define the root element for an XML tree

@XmlType(propOrder = { "field2", "field1",.. })

Allows to define the order in which the fields are written in the XML file

@XmlElement(name = "neuName")

Define the XML element which will be used. Only need to be used if the neuNeu is different than the JavaBeans Name

JAXB allows to define the used JAXB implementation via a service provider.

For example to convert a String into a annotate Task class annotated with the relevant JAXB annotation, you could use the following code:

JAXBContext jaxbContext = JAXBContext.newInstance(Task.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

StringReader reader = new StringReader("xml string here");
Task task = (Task) unmarshaller.unmarshal(reader);

1.2. Using JAXB with Java 11 or highter

With Java releases lower than Java 11, JAXB was part of the JVM and you could use it directly without defining additional libaries.

As of Java 11, JAXB is not part of the JRE anymore and you need to configure the relevant libraries via your dependency management system, for example Maven or Gradle. This tutorial demonstrates both approaches.

The JAXB reference implementation is developed on Github Jaxb api project page.

2. Tutorial: Using JAXB with Maven

Create a new Maven project called com.vogella.xml.jaxb.maven.

Configure the Java compiler level to be at least 11 and add the JAXB dependencies to your pom file.

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vogella</groupId>
    <artifactId>com.vogella.xml.jaxb.maven</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.3</version>
        </dependency>
    </dependencies>
</project>

Update your Maven settings, now you can use JAXB and continue with https://www.vogella.com/tutorials/JAXB/article.html#jaxb_tutorial.

3. Tutorial: Using JAXB with Gradle

Create a new Gradle project called com.vogella.xml.jaxb.gradle.

Adjust your build.gradle file to include the javax.xml.bind and org.eclipse.persistence libraries as dependencies to your Gradle plug-in.

plugins {
    // Apply the java-library plugin to add support for Java Library
    id 'java-library'
}

dependencies {
    implementation 'com.sun.xml.bind:jaxb-impl:2.3.3'
}

Update your Gradle settings, now you can use JAXB and continue with https://www.vogella.com/tutorials/JAXB/article.html#jaxb_tutorial.

4. Tutorial: Using JAXB in your code

After you used Maven or Gradle to make the JAXB libraries available you can start use it.

Create the following domain model.

package com.vogella.xml.jaxb.model;

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

@XmlRootElement(name = "book")
// If you want you can define the order in which the fields are written
// Optional
@XmlType(propOrder = { "author", "name", "publisher", "isbn" })
public class Book {

    private String name;
    private String author;
    private String publisher;
    private String isbn;

    // If you like the variable name, e.g. "name", you can easily change this
    // name for your XML-Output:
    @XmlElement(name = "title")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
}
package com.vogella.xml.jaxb.model;

import java.util.List;

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

//This statement means that class "Bookstore.java" is the root-element of our example
@XmlRootElement(namespace = "com.vogella.xml.jaxb.gradle.model")
public class Bookstore {

    // XmLElementWrapper generates a wrapper element around XML representation
    @XmlElementWrapper(name = "bookList")
    // XmlElement sets the name of the entities
    @XmlElement(name = "book")
    private List<Book> bookList;
    private String name;
    private String location;

    public void setBookList(List<Book> bookList) {
        this.bookList = bookList;
    }

    public List<Book> getBooksList() {
        return bookList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
}

Create the following test program for writing and reading the XML file.

package com.vogella.xml.jaxb.model;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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

public class BookMain {

    private static final String BOOKSTORE_XML = "./bookstore-jaxb.xml";

    public static void main(String[] args) throws JAXBException, IOException {

        var bookList = new ArrayList<Book>();

        // create books
        var book1 = new Book();
        book1.setIsbn("978-0060554736");
        book1.setName("The Game");
        book1.setAuthor("Neil Strauss");
        book1.setPublisher("Harpercollins");
        bookList.add(book1);

        var book2 = new Book();
        book2.setIsbn("978-3832180577");
        book2.setName("Feuchtgebiete");
        book2.setAuthor("Charlotte Roche");
        book2.setPublisher("Dumont Buchverlag");
        bookList.add(book2);

        // create bookstore, assigning book
        var bookstore = new Bookstore();
        bookstore.setName("Fraport Bookstore");
        bookstore.setLocation("Frankfurt Airport");
        bookstore.setBookList(bookList);

        // create JAXB context and instantiate marshaller
        JAXBContext context = JAXBContext.newInstance(Bookstore.class);
        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

        // Write to System.out
        m.marshal(bookstore, System.out);

        // Write to File
        m.marshal(bookstore, new File(BOOKSTORE_XML));

        // get variables from our xml file, created before
        System.out.println();
        System.out.println("Output from our XML File: ");
        Unmarshaller um = context.createUnmarshaller();
        Bookstore bookstore2 = (Bookstore) um.unmarshal(new FileReader(
                BOOKSTORE_XML));
        List<Book> list = bookstore2.getBooksList();
        for (Book book : list) {
            System.out.println("Book: " + book.getName() + " from "
                    + book.getAuthor());
        }
    }
}

If you run the BookMain an XML file will be created from the input objects. Afterwards the file is read again and the objects are re-created based on the XML file.

 

4.1. Links and Literature about JaxB

If you need more assistance we offer Online Training and Onsite training as well as consulting

See License for license information.

 

 

 

 

 

https://www.cnblogs.com/fish-king/archive/2013/04/01/2993730.html

 

@XmlRootElement   将一个Java类映射为一段XML的根节点

参数:name          定义这个根节点的名称

      namespace    定义这个根节点命名空间

@XmlAccessorType  定义映射这个类中的何种类型需要映射到XML。

@XmlAccessorType(XmlAccessType.FIELD)

可接收四个参数,分别是:

      XmlAccessType.FIELD:映射这个类中的所有字段到XML

      XmlAccessType.PROPERTY:映射这个类中的属性(get/set方法)到XML

      XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field或property同时映射到XML(默认)

      XmlAccessType.NONE:不映射

@XmlElement  指定一个字段或get/set方法映射到XML的节点。如,当一个类的XmlAccessorType 被标注为PROPERTY时,在某一个没有get/set方法的字段上标注此注解,即可将该字段映射到XML。

参数:defaultValue  指定节点默认值

         name             指定节点名称

         namespace    指定节点命名空间

         required         是否必须(默认为false)

         nillable           该字段是否包含nillable="true" 属性(默认为false)

         type               定义该字段或属性的关联类型

@XmlAttribute  指定一个字段或get/set方法映射到XML的属性。

参数:name             指定属性名称

         namespace    指定属性命名空间

         required         是否必须(默认为false)

@XmlTransient  定义某一字段或属性不需要被映射为XML。如,当一个类的XmlAccessorType被标注为PROPERTY时,在某一get/set方法的字段上标注此注解,那么该属性则不会被映射。

@XmlType  定义映射的一些相关规则

参数:propOrder        指定映射XML时的节点顺序

         factoryClass     指定UnMarshal时生成映射类实例所需的工厂类,默认为这个类本身

         factoryMethod  指定工厂类的工厂方法

         name               定义XML Schema中type的名称

         namespace      指定Schema中的命名空间

@XmlElementWrapper  为数组元素或集合元素定义一个父节点。

如,类中有一元素为List items,若不加此注解,该元素将被映射为

    <items>...</items>

    <items>...</items>

这种形式,此注解可将这个元素进行包装,如:

    @XmlElementWrapper(name="items")
    @XmlElement(name="item")
    public List items;

将会生成这样的XML样式:

    <items>

        <item>...</item>

        <item>...</item>

    </items>

@XmlJavaTypeAdapter  自定义某一字段或属性映射到XML的适配器。

如,类中包含一个接口,我们可以定义一个适配器(继承自javax.xml.bind.annotation.adapters.XmlAdapter类),指定这个接口如何映射到XML。

@XmlSchema 配置整个包的namespace,这个注解需放在package-info.java文件中。

 

 


 

一.Jaxb处理java对象和xml之间转换常用的annotation有:

  1. @XmlType
  2. @XmlElement
  3. @XmlRootElement
  4. @XmlAttribute
  5. @XmlAccessorType
  6. @XmlAccessorOrder
  7. @XmlTransient
  8. @XmlJavaTypeAdapter

 二.常用annotation使用说明

 

  1. @XmlType

  @XmlType用在class类的注解,常与@XmlRootElement,@XmlAccessorType一起使用。它有三个属性:name、propOrder、namespace,经常使用的只有前两个属性。如:

@XmlType(name = "basicStruct", propOrder = {
"intValue",
"stringArray",
"stringValue"
)
在使用@XmlType的propOrder 属性时,必须列出JavaBean对象中的所有属性,否则会报错。

  2.@XmlElement

  @XmlElement将java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。如:

  @XmlElement(name="Address")  
  private String yourAddress;

  3.@XmlRootElement

  @XmlRootElement用于类级别的注解,对应xml的跟元素,常与 @XmlType 和 @XmlAccessorType一起使用。如:

  @XmlType
  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlRootElement
  public class Address {}

  4.@XmlAttribute

  @XmlAttribute用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。如:
  @XmlAttribute(name="Country")
  private String state;

  5.@XmlAccessorType

  @XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式。常与@XmlRootElement、@XmlType一起使用。它的属性值是XmlAccessType的4个枚举值,分   别为:

  XmlAccessType.FIELD:java对象中的所有成员变量

  XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量

  XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量

  XmlAccessType.NONE:java对象的所有属性都不映射为xml的元素

  注意:@XmlAccessorType的默认访问级别是XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的getter/setter方法,就不要在   private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成xml时会报同一个属性在java类里存在两次的错误。同理,如果@XmlAccessorType的访问权限   为XmlAccessType.NONE,如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,这些成员变量依然可以映射到xml文件。

  6.@XmlAccessorOrder

  @XmlAccessorOrder用于对java对象生成的xml元素进行排序。它有两个属性值:

  AccessorOrder.ALPHABETICAL:对生成的xml元素按字母书序排序

  XmlAccessOrder.UNDEFINED:不排序

  7.@XmlTransient

  @XmlTransient用于标示在由java对象映射xml时,忽略此属性。即,在生成的xml文件中不出现此元素。

  8.@XmlJavaTypeAdapter

  @XmlJavaTypeAdapter常用在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。

  @XmlJavaTypeAdapter(value=xxx.class),value为自己定义的adapter类

  XmlAdapter如下:

public abstract class XmlAdapter<ValueType,BoundType> {
    // Do-nothing constructor for the derived classes.
    protected XmlAdapter() {}
    // Convert a value type to a bound type.
    public abstract BoundType unmarshal(ValueType v);
    // Convert a bound type to a value type.
    public abstract ValueType marshal(BoundType v);
 }

 三.示例

  1.Shop.java

package jaxb.shop;
 
import java.util.Set;
 
import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlAccessorOrder;
 
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "shop", propOrder = { "name", "number", "describer", "address","orders" })
@XmlRootElement(name = "CHMart")
public class Shop {
 
    @XmlAttribute
    private String name;
 
    // @XmlElement
    private String number;
 
    @XmlElement
    private String describer;
 
    @XmlElementWrapper(name = "orders")
    @XmlElement(name = "order")
    private Set<Order> orders;
 
    @XmlElement
    private Address address;
 
    public Shop() {
    }
 
    public Shop(String name, String number, String describer, Address address) {
        this.name = name;
        this.number = number;
        this.describer = describer;
        this.address = address;
    }
 
    getter/setter略
//同时使用了@XmlType(propOrder={})和@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL),但是生成的xml只按照propOrder定义的顺序生成元素

  2.Order.java

package jaxb.shop;
 
import java.math.BigDecimal;
import java.util.Date;
 
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
@XmlType(name="order",propOrder={"shopName","orderNumber","price","amount","purDate","customer"})
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Order {
 
//  @XmlElement  
    private String shopName;
 
    @XmlAttribute
    private String orderNumber;
 
//  @XmlElement
    @XmlJavaTypeAdapter(value=DateAdapter.class)
    private Date purDate;
 
//  @XmlElement
    private BigDecimal price;
 
//  @XmlElement
    private int amount;
 
//  @XmlElement
    private Customer customer;
 
    public Order() {
    }
 
    public Order(String shopName, String orderNumber, Date purDate,
            BigDecimal price, int amount) {
        this.shopName = shopName;
        this.orderNumber = orderNumber;
        this.purDate = purDate;
        this.price = price;
        this.amount = amount;
    }
getter/setter略
//@XmlAccessorType(XmlAccessType.FIELD),所以此处注释掉了@XmlElement,xml中依然会生成这些元素

  3.Customer.java

package jaxb.shop;
 
import java.util.Set;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
 
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Customer {
 
    @XmlAttribute
    private String name;
 
    private String gender;
 
    private String phoneNo;
 
    private Address address;
 
    private Set<Order> orders;
 
    public Customer() {
    }
 
    public Customer(String name, String gender, String phoneNo, Address address) {
        this.name = name;
        this.gender = gender;
        this.phoneNo = phoneNo;
        this.address = address;
    }
getter/setter略

  4.Address.java

package jaxb.shop;
 
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessorOrder;
 
@XmlType(propOrder={"state","province","city","street","zip"})
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
public class Address {
 
    @XmlAttribute 
    private String state;
     
    @XmlElement
    private String province;
     
    @XmlElement
    private String city;
 
    @XmlElement
    private String street;
     
    @XmlElement
    private String zip;
 
    public Address() {
        super();
    }
 
    public Address(String state, String province, String city, String street,
            String zip) {
        super();
        this.state = state;
        this.province = province;
        this.city = city;
        this.street = street;
        this.zip = zip;
    }
getter/setter略
//注意:虽然@XmlAccessorType为XmlAccessType.NONE,但是在java类的私有属性上加了@XmlAttribute和@XmlElement注解后,这些私有成员会映射生成xml的元素

  5.DateAdapter.java

package jaxb.shop;
 
import java.util.Date;
import java.text.SimpleDateFormat;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
 
public class DateAdapter extends XmlAdapter<String, Date> {
 
    private String pattern = "yyyy-MM-dd HH:mm:ss";
    SimpleDateFormat fmt = new SimpleDateFormat(pattern);
     
    @Override
    public Date unmarshal(String dateStr) throws Exception {
         
        return fmt.parse(dateStr);
    }
 
    @Override
    public String marshal(Date date) throws Exception {
         
        return fmt.format(date);
    }
 
}
//用于格式化日期在xml中的显示格式,并且由xml unmarshal为java对象时,将字符串解析为Date对象

  6.ShopTest.java

package jaxb.shop;
 
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
 
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
 
public class ShopTest {
 
    public static void main(String[] args) throws JAXBException, IOException{
        Set<Order> orders = new HashSet<Order>();
         
        Address address1 = new Address("China", "ShangHai", "ShangHai", "Huang", "200000");
        Customer customer1 = new Customer("Jim", "male", "13699990000", address1);
        Order order1 = new Order("Mart", "LH59900", new Date(), new BigDecimal(60), 1);
        order1.setCustomer(customer1);
         
        Address address2 = new Address("China", "JiangSu", "NanJing", "ZhongYangLu", "210000");
        Customer customer2 = new Customer("David", "male", "13699991000", address2);
        Order order2 = new Order("Mart", "LH59800", new Date(), new BigDecimal(80), 1);
        order2.setCustomer(customer2);
         
        orders.add(order1);
        orders.add(order2);
         
        Address address3 = new Address("China", "ZheJiang", "HangZhou", "XiHuRoad", "310000");
        Shop shop = new Shop("CHMart", "100000", "EveryThing",address3);
        shop.setOrder(orders);
         
         
        FileWriter writer = null;
        JAXBContext context = JAXBContext.newInstance(Shop.class);
        try {
            Marshaller marshal = context.createMarshaller();
            marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshal.marshal(shop, System.out);
             
            writer = new FileWriter("shop.xml");
            marshal.marshal(shop, writer);
        } catch (Exception e) {
            e.printStackTrace();
        }
         
        Unmarshaller unmarshal = context.createUnmarshaller();
        FileReader reader = new FileReader("shop.xml") ;
        Shop shop1 = (Shop)unmarshal.unmarshal(reader);
         
        Set<Order> orders1 = shop1.getOrder();
        for(Order order : orders1){
            System.out.println("***************************");
            System.out.println(order.getOrderNumber());
            System.out.println(order.getCustomer().getName());
            System.out.println("***************************");
        }
    }
}

  7.生成的xml文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CHMart name="CHMart">
    <number>100000</number>
    <describer>EveryThing</describer>
    <address state="China">
        <province>ZheJiang</province>
        <city>HangZhou</city>
        <street>XiHuRoad</street>
        <zip>310000</zip>
    </address>
    <orders>
        <order orderNumber="LH59800">
            <shopName>Mart</shopName>
            <price>80</price>
            <amount>1</amount>
            <purDate>2012-03-25 12:57:23</purDate>
            <customer name="David">
                <gender>male</gender>
                <phoneNo>13699991000</phoneNo>
                <address state="China">
                    <province>JiangSu</province>
                    <city>NanJing</city>
                    <street>ZhongYangLu</street>
                    <zip>210000</zip>
                </address>
            </customer>
        </order>
        <order orderNumber="LH59900">
            <shopName>Mart</shopName>
            <price>60</price>
            <amount>1</amount>
            <purDate>2012-03-25 12:57:23</purDate>
            <customer name="Jim">
                <gender>male</gender>
                <phoneNo>13699990000</phoneNo>
                <address state="China">
                    <province>ShangHai</province>
                    <city>ShangHai</city>
                    <street>Huang</street>
                    <zip>200000</zip>
                </address>
            </customer>
        </order>
    </orders>
</CHMart>

  以上是以一个简单的商店订单模型作为示例。

posted @   A-P-I  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示