on  It Road.com

问题

使用 JAXB 将 java 对象(集合类型)编组为 xml 格式时,会发生此异常。

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "employees"

java.util.Map is an interface, and JAXB can't handle interfaces.
	this problem is related to the following location:
		at public java.util.List com.onitroad.jaxb.examples.list.Employees.getEmployees()
		at com.onitroad.jaxb.examples.list.Employees
	this problem is related to the following location:
		at private java.util.List com.onitroad.jaxb.examples.list.Employees.employees
		at com.onitroad.jaxb.examples.list.Employees
	at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(Unknown Source)
	..... more

原因

发生上述异常主要是因为没有@XmlAccessType 注释或者@XmlAccessType 与@XxmlElement 注释无效使用。
正确的用法是一个 java 字段应该只有一个有效的 JAXB 注释来表示它的元数据。

默认情况下,JAXB 包括所有公共字段和用于编组的 getter。
所以如果你有一个字段,它的吸气剂会被包含两次。
这是错误的,需要通过正确使用注释来解决。

解决方案:使用@XmlAccessType 注解

  1. @XmlAccessorType (XmlAccessType.FIELD)

如果我们使用的是 XmlAccessType.FIELD; 那么只有所有公共字段(非静态)将自动包含在编组中。
不会考虑 getter。
因此,如果将消除重复问题。
例如,在下面的代码中,员工和规模字段都将包括在内。

注意“@XmlElement(name="employee")”是可选的;我用它来重命名输出 xml 中的 xml 节点。
如果你删除它;不会有任何编组错误或者异常。

@XmlRootElement(name = "employees")
@XmlAccessorType (XmlAccessType.FIELD)
public class Employees 
{
	@XmlElement(name="employee")
	private List<Employee> employees = null;

	private Integer size;
	public List<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}
	public Integer getSize() {
		return size;
	}
	public void setSize(Integer size) {
		this.size = size;
	}
}
  1. @XmlAccessorType (XmlAccessType.NONE)

如果我们使用的是“XmlAccessType.NONE”,则意味着我们必须在输出 XML 中注释所有要编组的字段。
剩下的任何字段都不会包含在 JAXB 上下文中。
所以本质上,“员工”和“规模”字段都需要@XmlElement 注释。
如果两个字段中的任何一个都没有使用 @XmlElement 进行注释,则不会对其进行编组。

@XmlRootElement(name = "employees")
@XmlAccessorType (XmlAccessType.NONE)
public class Employees 
{
	@XmlElement(name="employee")
	private List<Employee> employees = null;

	@XmlElement(name="size")
	private Integer size;
	public List<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}
	public Integer getSize() {
		return size;
	}
	public void setSize(Integer size) {
		this.size = size;
	}
}
JAXB bind.v2.runtime.IllegalAnnotationsException
日期:2020-09-17 00:09:31 来源:oir作者:oir