# 没有`@XmlRootElement`的 JAXB 编组 – 缺少`@XmlRootElement`错误

> 原文： [https://howtodoinjava.com/jaxb/marshal-without-xmlrootelement/](https://howtodoinjava.com/jaxb/marshal-without-xmlrootelement/)

很多时候，我们将需要**编组 Java 对象，而不使用 [JAXB 注释](https://howtodoinjava.com/jaxb/jaxb-annotations/)**，例如[`@XmlRootElement`](https://howtodoinjava.com/jaxb/xmlrootelement-annotation/)，并且我们不允许在源代码中进行任何更改。 当我们使用遗留代码或某些我们没有源代码的客户端 jar 时，可能会发生这种情况。

可能还有许多其他情况，但是想法是*我们无法使用 JAXB 注解*修改模型类。 这可能是**将 Java 对象转换为 xml 而没有 jaxb** 的示例。

## 1.没有`@XmlRootElement`进行编组时出现问题

在这种情况下，如果我们尝试将[将 Java 对象直接编组为 XML](https://howtodoinjava.com/jaxb/write-object-to-xml/)，则将得到类似的错误。

```java
javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "com.howtodoinjava.demo.model.Employee" 
as an element because it is missing an @XmlRootElement annotation]
  at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)
  at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
  at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:95)
  at com.howtodoinjava.demo.JaxbExample.jaxbObjectToXML(JaxbExample.java:45)
  at com.howtodoinjava.demo.JaxbExample.main(JaxbExample.java:17)
Caused by: com.sun.istack.internal.SAXException2: unable to marshal type "com.howtodoinjava.demo.model.Employee" 
as an element because it is missing an @XmlRootElement annotation
  at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:234)
  at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:323)
  at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:479)
  at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:308)
  ... 4 more

```

其中`Employee.java`类如下。 它没有任何`@XmlRootElement`这样的 JAXB 注解。

```java
package com.howtodoinjava.demo.model;

import java.io.Serializable;

public class Employee implements Serializable {

  private static final long serialVersionUID = 1L;

  private Integer id;
  private String firstName;
  private String lastName;
  private Department department;

  public Employee() {
    super();
  }

  public Employee(int id, String fName, String lName, Department department) {
    super();
    this.id = id;
    this.firstName = fName;
    this.lastName = lName;
    this.department = department;
  }

  //Getters and Setters

  @Override
  public String toString() {
    return "Employee [id=" + id + ", firstName=" + firstName + ", 
       lastName=" + lastName + ", department=" + department + "]";
  }
}

```

## 2.没有`@XmlRootElement`注解的对象的解决方案

缺少`@XmlRootElement`注解时，JAXB 无法为`Employee`对象构建[`JAXBElement`](https://docs.oracle.com/javaee/7/api/javax/xml/bind/JAXBElement.html)实例。 这就是我们必须帮助 JAXB 手动构建它的地方。

#### 2.1 语法

```java
/**
  * @param name          Java binding of xml element tag name
  * @param declaredType  Java binding of xml element declaration's type
  * @param value         Java instance representing xml element's value
  */
JAXBElement<T> elem = new JAXBElement(QName name, Class<T> declaredType, T value );

```

例如：

```java
JAXBElement<Employee> jaxbElement 
        = new JAXBElement<Employee>( new QName("", "employee"), Employee.class, employeeObj );

```

#### 2.2 没有`@XmlRootElement`的 JAXB 编组示例

现在，让我们看看该编组代码的工作原理。

```java
package com.howtodoinjava.demo;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;

import com.howtodoinjava.demo.model.Department;
import com.howtodoinjava.demo.model.Employee;

public class JaxbExample 
{
  public static void main(String[] args) 
  {
    Employee employee = new Employee(1, "Lokesh", "Gupta", new Department(101, "IT"));

    jaxbObjectToXML( employee );
  }

  private static void jaxbObjectToXML(Employee employeeObj) 
  {
      try {
          JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
          Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

          // To format XML
          jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 

          //If we DO NOT have JAXB annotated class
          JAXBElement<Employee> jaxbElement = 
            new JAXBElement<Employee>( new QName("", "employee"), 
                      Employee.class, 
                      employeeObj);

          jaxbMarshaller.marshal(jaxbElement, System.out);

          //If we have JAXB annotated class
          //jaxbMarshaller.marshal(employeeObj, System.out);  

      } catch (JAXBException e) {
          e.printStackTrace();
      }
  }
}

```

程序输出：

```java
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
    <department>
        <id>101</id>
        <name>IT</name>
    </department>
    <firstName>Lokesh</firstName>
    <id>1</id>
    <lastName>Gupta</lastName>
</employee>

```

请向我提供关于没有`@XmlRootElement`的 *JAXB 编组*示例的问题。

学习愉快！

参考： [`XmlRootElement` Java 文档](https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlRootElement.html)