问题
使用 JAXB 将 java 对象(集合类型)编组为 xml 格式时,会发生此异常。
Exception in thread "main" javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context. at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(Unknown Source) at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(Unknown Source) at com.onitroad.jaxb.examples.list.TestEmployeeMarshing.main(TestEmployeeMarshing.java:58)
欢迎来到之路教程(on itroad-com)
原因
发生上述异常是因为 JAXB 总是期望实体上有一个 @XmlRootElement 注释,它会被封送。
这是强制性的,不能跳过。
这个@XmlRootElement 注释需要从从 java 对象编组的 XML 的根元素获取元数据。
ArrayList 类或者任何 Java 集合类都没有任何 JAXB 注释。
由于此 JAXB 无法解析任何此类 java 对象并引发此错误。
解决方案
创建包装类
这是推荐的方法,因为它使我们可以灵活地在未来添加/删除字段,例如大小属性。
@XmlRootElement(name = "employees") @XmlAccessorType (XmlAccessType.FIELD) public class Employees { @XmlElement(name = "employee") private List<Employee> employees = null; public List<Employee> getEmployees() { return employees; } public void setEmployees(List<Employee> employees) { this.employees = employees; } }
现在你可以使用这个类,如下所示:
static Employees employees = new Employees(); static { employees.setEmployees(new ArrayList<Employee>()); Employee emp1 = new Employee(); emp1.setId(1); emp1.setFirstName("JackLi"); emp1.setLastName("Gupta"); emp1.setIncome(100.0); Employee emp2 = new Employee(); emp2.setId(2); emp2.setFirstName("John"); emp2.setLastName("Mclane"); emp2.setIncome(200.0); employees.getEmployees().add(emp1); employees.getEmployees().add(emp2); } private static void marshalingExample() throws JAXBException { JAXBContext jaxbContext = JAXBContext.newInstance(Employees.class); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); jaxbMarshaller.marshal(employees, System.out); }
日期:2020-09-17 00:09:41 来源:oir作者:oir