原文: https://howtodoinjava.com/jaxb/marshal-without-xmlrootelement/

很多时候,我们将需要编组 Java 对象,而不使用 JAXB 注解,例如@XmlRootElement,并且我们不允许在源代码中进行任何更改。 当我们使用遗留代码或某些我们没有源代码的客户端 jar 时,可能会发生这种情况。

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

1.不带@XmlRootElement的编组问题

在这种情况下,如果我们尝试将将 Java 对象直接编组为 XML,则将得到类似的错误。

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

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

  1. package com.howtodoinjava.demo.model;
  2. import java.io.Serializable;
  3. public class Employee implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. private Integer id;
  6. private String firstName;
  7. private String lastName;
  8. private Department department;
  9. public Employee() {
  10. super();
  11. }
  12. public Employee(int id, String fName, String lName, Department department) {
  13. super();
  14. this.id = id;
  15. this.firstName = fName;
  16. this.lastName = lName;
  17. this.department = department;
  18. }
  19. //Getters and Setters
  20. @Override
  21. public String toString() {
  22. return "Employee [id=" + id + ", firstName=" + firstName + ",
  23. lastName=" + lastName + ", department=" + department + "]";
  24. }
  25. }

2.不带@XmlRootElement注解的编组的解决方案

缺少@XmlRootElement注解时,JAXB 无法为Employee对象构建JAXBElement实例。 这就是我们必须帮助 JAXB 手动构建它的地方。

2.1 语法

  1. /**
  2. * @param name Java binding of xml element tag name
  3. * @param declaredType Java binding of xml element declaration's type
  4. * @param value Java instance representing xml element's value
  5. */
  6. JAXBElement<T> elem = new JAXBElement(QName name, Class<T> declaredType, T value );

例如:

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

2.2 不带@XmlRootElement的 JAXB 编组示例

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

  1. package com.howtodoinjava.demo;
  2. import javax.xml.bind.JAXBContext;
  3. import javax.xml.bind.JAXBElement;
  4. import javax.xml.bind.JAXBException;
  5. import javax.xml.bind.Marshaller;
  6. import javax.xml.namespace.QName;
  7. import com.howtodoinjava.demo.model.Department;
  8. import com.howtodoinjava.demo.model.Employee;
  9. public class JaxbExample
  10. {
  11. public static void main(String[] args)
  12. {
  13. Employee employee = new Employee(1, "Lokesh", "Gupta", new Department(101, "IT"));
  14. jaxbObjectToXML( employee );
  15. }
  16. private static void jaxbObjectToXML(Employee employeeObj)
  17. {
  18. try {
  19. JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
  20. Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
  21. // To format XML
  22. jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
  23. //If we DO NOT have JAXB annotated class
  24. JAXBElement<Employee> jaxbElement =
  25. new JAXBElement<Employee>( new QName("", "employee"),
  26. Employee.class,
  27. employeeObj);
  28. jaxbMarshaller.marshal(jaxbElement, System.out);
  29. //If we have JAXB annotated class
  30. //jaxbMarshaller.marshal(employeeObj, System.out);
  31. } catch (JAXBException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. }

程序输出:

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <employee>
  3. <department>
  4. <id>101</id>
  5. <name>IT</name>
  6. </department>
  7. <firstName>Lokesh</firstName>
  8. <id>1</id>
  9. <lastName>Gupta</lastName>
  10. </employee>

请向我提供关于没有@XmlRootElementJAXB 编组示例的问题。

学习愉快!

参考: XmlRootElement Java 文档