问题
解组时没有jaxb注解, 在这种情况下,如果我们尝试直接将 Java 对象解组为 XML,则会出现这样的错误。
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"employee"). Expected elements are (none) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:379) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:605) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3138) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:880) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189) at com.onitroad.demo.JaxbExample.jaxbXmlFileToObject(JaxbExample.java:63) at com.onitroad.demo.JaxbExample.main(JaxbExample.java:21)
其中Employee.java
类如下。
它没有任何 JAXB 注释,例如 @XmlRootElement
。
package com.onitroad.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 + "]"; } }
https://onitroad.com 更多教程
无jaxb注解解组的解决方法
由于没有 @XmlRootElement
注释,JAXB 无法为 Employee
对象构建 JAXBElement
实例。
所以这就是我们必须帮助 JAXB 手动构建它的地方。
语法
/** * Unmarshal XML data from the specified XML Source by <tt>declaredType</tt> and return the * resulting content tree. * @param source source the XML Source to unmarshal XML data from (providers are * only required to support SAXSource, DOMSource, and StreamSource) * * @param declaredType appropriate JAXB mapped class to hold <tt>source</tt>'s xml root element * * @return value Java content rooted by JAXB Element */ public <T> JAXBElement<T> unmarshal( javax.xml.transform.Source source, Class<T> declaredType ) throws JAXBException;
例如
JAXBElement<Employee> jaxbElement = (JAXBElement<Employee>) jaxbUnmarshaller .unmarshal(new StreamSource(xmlFile), Employee.class);
解组
现在让我们看看这个解组代码是如何工作的。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <employee> <department> <id>101</id> <name>IT</name> </department> <firstName>JackLi</firstName> <id>1</id> <lastName>Gupta</lastName> </employee>
package com.onitroad.demo; import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamSource; import com.onitroad.demo.model.Employee; public class JaxbExample { public static void main(String[] args) { String fileName = "employee.xml"; jaxbXmlFileToObject(fileName); } private static void jaxbXmlFileToObject(String fileName) { File xmlFile = new File(fileName); JAXBContext jaxbContext; try { jaxbContext = JAXBContext.newInstance(Employee.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); JAXBElement<Employee> jaxbElement = (JAXBElement<Employee>) jaxbUnmarshaller .unmarshal(new StreamSource(xmlFile), Employee.class); Employee employee = jaxbElement.getValue(); System.out.println(employee); } catch (JAXBException e) { e.printStackTrace(); } } }
程序输出:
Employee [id=1, firstName=JackLi, lastName=Gupta, department=Department [id=101, name=IT]]
日期:2020-09-17 00:09:40 来源:oir作者:oir