JAXB 注释问题
JAXB annotation issue
我需要一些关于 JAXB 注释的帮助。我有一个 XML,我想将其作为 java 对象获取。
如果我按原样 运行 ,我将收到有关具有相同名称的属性的错误消息(见下文)。当我在功能和场景 类 中注释掉列表的设置器时,错误将消失,但我将需要那些设置器...
错误:
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
Class has two properties of the same name "scenarioList"
this problem is related to the following location:
at public java.util.ArrayList generator.model.Feature.getScenarioList()
at generator.model.Feature
at private java.util.ArrayList generator.model.Features.featureList
at generator.model.Features
this problem is related to the following location:
at private java.util.ArrayList generator.model.Feature.scenarioList
at generator.model.Feature
at private java.util.ArrayList generator.model.Features.featureList
at generator.model.Features
Class has two properties of the same name "stepList"
this problem is related to the following location:
at public java.util.ArrayList generator.model.Scenario.getStepList()
at generator.model.Scenario
at private java.util.ArrayList generator.model.Feature.scenarioList
at generator.model.Feature
at private java.util.ArrayList generator.model.Features.featureList
at generator.model.Features
this problem is related to the following location:
at private java.util.ArrayList generator.model.Scenario.stepList
at generator.model.Scenario
at private java.util.ArrayList generator.model.Feature.scenarioList
at generator.model.Feature
at private java.util.ArrayList generator.model.Features.featureList
at generator.model.Features
XML解析:
<?xml version="1.0" encoding="UTF-8"?>
<features>
<feature id="1">
<name>Feature name 1</name>
<description>Feature description 1</description>
<scenarios>
<scenario id="1">
<name>Scenario name 1</name>
<steps>
<step id="1"></step>
<step id="2"></step>
</steps>
</scenario>
<scenario id="2">
<name>Scenario name 2</name>
<steps>
<step id="1"></step>
<step id="2"></step>
</steps>
</scenario>
</scenarios>
</feature>
<feature id="2">
<name>Feature name 2</name>
<description>Feature description 2</description>
<scenarios>
<scenario id="4">
<name>Scenario name 1</name>
<steps>
<step id="1"></step>
</steps>
</scenario>
</scenarios>
</feature>
</features>
这是模型 类:
Features.java
package generator.model;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "features")
public class Features {
@XmlElement(name = "feature")
private ArrayList<Feature> featureList = null;
public void setFeaturesList(ArrayList<Feature> featureList) {
this.featureList = featureList;
}
public ArrayList<Feature> getFeatureList() {
return featureList;
}
}
Feature.java
package generator.model;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "feature")
public class Feature {
@XmlElementWrapper(name = "scenarios")
@XmlElement(name= "scenario")
private ArrayList<Scenario> scenarioList = null;
private int id;
private String name;
private String description;
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ArrayList<Scenario> getScenarioList() {
return scenarioList;
}
public void setScenarioList(ArrayList<Scenario> scenarioList) {
this.scenarioList = scenarioList;
}
}
Scenario.java
package generator.model;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "scenario")
public class Scenario {
@XmlElementWrapper(name = "steps")
@XmlElement(name= "step")
private ArrayList<Step> stepList = null;
private int id;
private String name;
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Step> getStepList() {
return stepList;
}
public void setStepList(ArrayList<Step> stepList) {
this.stepList = stepList;
}
}
Step.java
package generator.model;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "step")
public class Step {
private int id;
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
JAXB 自动映射字段或属性。如果 @XmlAccessorType
不存在,则默认为 XmlAccessType.PUBLIC_MEMBER
,即 (see javadoc)
Every public getter/setter pair and every public field will be automatically bound to XML, unless annotated by XmlTransient.
在您的情况下,默认情况下,所有 public
getter/setter 都会被映射,即使不存在注释也是如此。字段未映射,因为它们是 private
,除非明确注释。
所以,与映射两次的stepList
和scenarioList
有冲突:public
getter/setter,因为@XmlAccessorType
不存在,和字段,因为它被注释了。
请注意,在您的功能 class 中,您将有一个 <feature>
元素(带注释的私有功能列表字段)和一个 <featureList>
元素(public getter 用于 featureList),两者具有相同的内容。
你可以避免它,在 属性 getter 中添加一个 @XmlTransient
注释来避免自动映射。但我建议选择映射字段或属性,并相应地指定 @XmlAccessorType。
例如,您的 Scenario.java 可以映射为:
// Non static, non transient fields will be automatically be mapped unless annotated with XmlTransient.
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "scenario")
public class Scenario {
@XmlElementWrapper(name = "steps")
@XmlElement(name= "step")
private ArrayList<Step> stepList = null;
@XmlAttribute
private int id;
// Mapping a field to an element is the default, so this annotation is not strictly
// needed, unless you want to change the default element name
@XmlElement
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Step> getStepList() {
return stepList;
}
public void setStepList(ArrayList<Step> stepList) {
this.stepList = stepList;
}
}
我需要一些关于 JAXB 注释的帮助。我有一个 XML,我想将其作为 java 对象获取。 如果我按原样 运行 ,我将收到有关具有相同名称的属性的错误消息(见下文)。当我在功能和场景 类 中注释掉列表的设置器时,错误将消失,但我将需要那些设置器...
错误:
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
Class has two properties of the same name "scenarioList"
this problem is related to the following location:
at public java.util.ArrayList generator.model.Feature.getScenarioList()
at generator.model.Feature
at private java.util.ArrayList generator.model.Features.featureList
at generator.model.Features
this problem is related to the following location:
at private java.util.ArrayList generator.model.Feature.scenarioList
at generator.model.Feature
at private java.util.ArrayList generator.model.Features.featureList
at generator.model.Features
Class has two properties of the same name "stepList"
this problem is related to the following location:
at public java.util.ArrayList generator.model.Scenario.getStepList()
at generator.model.Scenario
at private java.util.ArrayList generator.model.Feature.scenarioList
at generator.model.Feature
at private java.util.ArrayList generator.model.Features.featureList
at generator.model.Features
this problem is related to the following location:
at private java.util.ArrayList generator.model.Scenario.stepList
at generator.model.Scenario
at private java.util.ArrayList generator.model.Feature.scenarioList
at generator.model.Feature
at private java.util.ArrayList generator.model.Features.featureList
at generator.model.Features
XML解析:
<?xml version="1.0" encoding="UTF-8"?>
<features>
<feature id="1">
<name>Feature name 1</name>
<description>Feature description 1</description>
<scenarios>
<scenario id="1">
<name>Scenario name 1</name>
<steps>
<step id="1"></step>
<step id="2"></step>
</steps>
</scenario>
<scenario id="2">
<name>Scenario name 2</name>
<steps>
<step id="1"></step>
<step id="2"></step>
</steps>
</scenario>
</scenarios>
</feature>
<feature id="2">
<name>Feature name 2</name>
<description>Feature description 2</description>
<scenarios>
<scenario id="4">
<name>Scenario name 1</name>
<steps>
<step id="1"></step>
</steps>
</scenario>
</scenarios>
</feature>
</features>
这是模型 类:
Features.java
package generator.model;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "features")
public class Features {
@XmlElement(name = "feature")
private ArrayList<Feature> featureList = null;
public void setFeaturesList(ArrayList<Feature> featureList) {
this.featureList = featureList;
}
public ArrayList<Feature> getFeatureList() {
return featureList;
}
}
Feature.java
package generator.model;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "feature")
public class Feature {
@XmlElementWrapper(name = "scenarios")
@XmlElement(name= "scenario")
private ArrayList<Scenario> scenarioList = null;
private int id;
private String name;
private String description;
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ArrayList<Scenario> getScenarioList() {
return scenarioList;
}
public void setScenarioList(ArrayList<Scenario> scenarioList) {
this.scenarioList = scenarioList;
}
}
Scenario.java
package generator.model;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "scenario")
public class Scenario {
@XmlElementWrapper(name = "steps")
@XmlElement(name= "step")
private ArrayList<Step> stepList = null;
private int id;
private String name;
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Step> getStepList() {
return stepList;
}
public void setStepList(ArrayList<Step> stepList) {
this.stepList = stepList;
}
}
Step.java
package generator.model;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "step")
public class Step {
private int id;
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
JAXB 自动映射字段或属性。如果 @XmlAccessorType
不存在,则默认为 XmlAccessType.PUBLIC_MEMBER
,即 (see javadoc)
Every public getter/setter pair and every public field will be automatically bound to XML, unless annotated by XmlTransient.
在您的情况下,默认情况下,所有 public
getter/setter 都会被映射,即使不存在注释也是如此。字段未映射,因为它们是 private
,除非明确注释。
所以,与映射两次的stepList
和scenarioList
有冲突:public
getter/setter,因为@XmlAccessorType
不存在,和字段,因为它被注释了。
请注意,在您的功能 class 中,您将有一个 <feature>
元素(带注释的私有功能列表字段)和一个 <featureList>
元素(public getter 用于 featureList),两者具有相同的内容。
你可以避免它,在 属性 getter 中添加一个 @XmlTransient
注释来避免自动映射。但我建议选择映射字段或属性,并相应地指定 @XmlAccessorType。
例如,您的 Scenario.java 可以映射为:
// Non static, non transient fields will be automatically be mapped unless annotated with XmlTransient.
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "scenario")
public class Scenario {
@XmlElementWrapper(name = "steps")
@XmlElement(name= "step")
private ArrayList<Step> stepList = null;
@XmlAttribute
private int id;
// Mapping a field to an element is the default, so this annotation is not strictly
// needed, unless you want to change the default element name
@XmlElement
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Step> getStepList() {
return stepList;
}
public void setStepList(ArrayList<Step> stepList) {
this.stepList = stepList;
}
}