# Java JAXB 教程

原文：http://zetcode.com/java/jaxb/

Java JAXB 教程显示了如何使用 JAXB 库来处理 XML。 这些示例将 Java 对象写入 XML 文件，并将 XML 数据读取到 Java 对象。

## JAXB

用于 XML 绑定的 Java 体系结构（JAXB）是允许 Java 开发人员将 Java 类映射到 XML 表示形式的软件框架。 JAXB 支持将 Java 对象编组为 XML，然后将 XML 解组为 Java 对象。

在 Java 9 中，JAXB 已移至单独的模块`java.xml`中。 在 Java 9 和 Java 10 中，我们需要使用`--add-modules=java.xml.bind`选项。 在 Java 11 中，JAXB 已从 JDK 中删除，我们需要通过 Maven 或 Gradle 将其作为单独的库添加到项目中。

在我们的示例中，我们使用 JDK 11 和 Maven 创建我们的应用。

## JAXB 定义

编组是将 Java 对象转换为 XML 文档的过程。 解组是将 XML 文档读入 Java 对象的过程。 `JAXBContext`类提供客户端到 JAXB API 的入口点。 它提供用于编组，解组和验证的 API。

## JAXB POM 设置

以下 POM 文件包含必需的 JAXB JAR。

`pom.xml`

```java
<?xml version="1.0" encoding="UTF-8"?>
<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 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>JavaWriteXmlJaxbEx</groupId>
    <artifactId>JavaWriteXmlJaxbEx</artifactId>
    <version>1.0-SNAPSHOT</version>

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

    <dependencies>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>

                    <archive>
                        <manifest>
                            <mainClass>com.zetcode.JavaWriteXmlJaxbEx</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

```

除了包括 JAXB 依赖项，我们还使用`maven-assembly-plugin`将所有依赖项打包到一个 JAR 中。

## JAXB 编写 XML 示例

在第一个示例中，我们将 Java 对象写入 XML 文件。

`Book.java`

```java
package com.zetcode;

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

@XmlRootElement(name = "book")

// Defining order
@XmlType(propOrder = { "author", "name", "publisher", "isbn" })
public class Book {

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

    // Changing to title
    @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;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Book{");
        sb.append("name='").append(name).append('\'');
        sb.append(", author='").append(author).append('\'');
        sb.append(", publisher='").append(publisher).append('\'');
        sb.append(", isbn='").append(isbn).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

```

这是`Book` bean。 该 bean 将被转换为特定的 XML 标签。

```java
@XmlRootElement(name = "book")

```

使用`@XmlRootElement`注解，我们定义 XML 标签名称。

```java
@XmlType(propOrder = { "author", "name", "publisher", "isbn" })

```

通过`@XmlType`的`propOrder`属性，我们定义了子元素的顺序。

```java
@XmlElement(name = "title")
public String getName() {
    return name;
}

```

我们可以将默认元素名称更改为`title`。

`BookStore.java`

```java
package com.zetcode;

import java.util.ArrayList;
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.zetcode")
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 ArrayList<Book> bookList;
    private String name;
    private String location;

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

    public ArrayList<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;
    }
}

```

`BookStore`是一个类，其中包含一个列表，我们在其中放置书本对象。

```java
@XmlRootElement(namespace = "com.zetcode")
public class BookStore {

```

我们用`@XmlRootElement`注释定义根元素。

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

```

`@XmlElementWrapper`注释在`book`元素周围定义了包装元素。 `@XmlElement`注解定义包装器内的 XML 元素的名称。

`JavaWriteXmlJaxbEx.java`

```java
package com.zetcode;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.File;
import java.util.ArrayList;

public class JavaWriteXmlJaxbEx {

    private static final String BOOKSTORE_XML = "src/main/resources/bookstore.xml";

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

        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, assign books
        var bookstore = new BookStore();
        bookstore.setName("Fraport Bookstore");
        bookstore.setLocation("Livres belles");
        bookstore.setBookList(bookList);

        // create JAXB context and instantiate marshaller
        var context = JAXBContext.newInstance(BookStore.class);
        var 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));
    }
}

```

在示例中，我们创建书对象，将它们添加到书店，然后将书店转换为 XML 文件。

```java
// 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);

```

我们创建两个书本对象。

```java
// create bookstore, assign books
var bookstore = new BookStore();
bookstore.setName("Fraport Bookstore");
bookstore.setLocation("Livres belles");
bookstore.setBookList(bookList);

```

创建了一个书店并将书籍放入其中。

```java
// create JAXB context and instantiate marshaller
var context = JAXBContext.newInstance(BookStore.class);

```

我们创建一个新的`JAXBContext`。 我们传递新上下文对象必须识别的类的列表。 （在我们的例子中，这是一类。）

```java
var m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

```

从上下文中，我们得到了`createMarshaller()`的编组器。 我们设置一个属性以获取格式化输出。

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

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

```

我们将数据写入系统输出和文件中。

## JAXB 读取 XML 示例

在第二个示例中，我们将编组的数据读回到 Java 对象中。

`JavaReadXmlJaxbEx.java`

```java
package com.zetcode;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class JavaReadXmlJaxbEx {

    private static final String BOOKSTORE_XML = "src/main/resources/bookstore.xml";

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

        // create JAXB context and unmarshaller
        var context = JAXBContext.newInstance(BookStore.class);
        var um = context.createUnmarshaller();

        var bookstore = (BookStore) um.unmarshal(new InputStreamReader(
                new FileInputStream(BOOKSTORE_XML), StandardCharsets.UTF_8));
        var bookList = bookstore.getBooksList();

        bookList.forEach((book) -> {
            System.out.println(book);
        });
    }
}

```

该示例从`bookstore.xml`文档中读取书籍。

```java
// create JAXB context and unmarshaller
var context = JAXBContext.newInstance(BookStore.class);
var um = context.createUnmarshaller();

```

我们创建一个 JAXB 上下文并获得一个新的解组器。

```java
var bookstore = (BookStore) um.unmarshal(new InputStreamReader(
        new FileInputStream(BOOKSTORE_XML), StandardCharsets.UTF_8));

```

使用`unmarshal()`，我们从 XML 文档中读取数据。

```java
var bookList = bookstore.getBooksList();

bookList.forEach((book) -> {
    System.out.println(book);
});

```

我们获得书籍列表并对其进行遍历。

```java
Book{name='The Game', author='Neil Strauss', publisher='Harpercollins', isbn='978-0060554736'}
Book{name='Feuchtgebiete', author='Charlotte Roche', publisher='Dumont Buchverlag', isbn='978-3832180577'}

```

这是输出。

在本教程中，我们已经使用 Java JAXB 库读写 XML 文件。 您可能也对相关教程感兴趣： [Java DOM 教程](/java/dom/)， [Java SAX 教程](/java/sax/)， [Java JSON 处理教程](/java/jsonp/)和 [Java 教程](/lang/java/) 。