原文: https://howtodoinjava.com/jaxb/marshal-without-xmlrootelement/
很多时候,我们将需要编组 Java 对象,而不使用 JAXB 注解,例如@XmlRootElement,并且我们不允许在源代码中进行任何更改。 当我们使用遗留代码或某些我们没有源代码的客户端 jar 时,可能会发生这种情况。
可能还有许多其他情况,但是想法是我们无法使用 JAXB 注解修改模型类。 这可能是将 Java 对象转换为 xml 而没有 jaxb 的示例。
1.不带@XmlRootElement的编组问题
在这种情况下,如果我们尝试将将 Java 对象直接编组为 XML,则将得到类似的错误。
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 annotationat 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 注解。
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@Overridepublic String toString() {return "Employee [id=" + id + ", firstName=" + firstName + ",lastName=" + lastName + ", department=" + department + "]";}}
2.不带@XmlRootElement注解的编组的解决方案
缺少@XmlRootElement注解时,JAXB 无法为Employee对象构建JAXBElement实例。 这就是我们必须帮助 JAXB 手动构建它的地方。
2.1 语法
/*** @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 );
例如:
JAXBElement<Employee> jaxbElement= new JAXBElement<Employee>( new QName("", "employee"), Employee.class, employeeObj );
2.2 不带@XmlRootElement的 JAXB 编组示例
现在,让我们看看该编组代码的工作原理。
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 XMLjaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);//If we DO NOT have JAXB annotated classJAXBElement<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();}}}
程序输出:
<?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 编组示例的问题。
学习愉快!
