Я не нашел подобной проблемы, поэтому я понятия не имею, возможно ли это или нет.
У меня есть пара классов с одинаковым наследованием. Мой основной класс - Material, а затем у меня есть MaterialTypeA, B, C... Все эти классы имеют разные атрибуты.
До сих пор мой основной класс такой.
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public abstract class Material {
@XmlElement
private String name;
private String details;
...
Другие классы:
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class MaterialTypeA extends Material {
@XmlElement
private String propertyA1;
private String propertyB2;
...
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class MaterialTypeB extends Material {
@XmlElement
private String propertyB1;
private String propertyB2;
...
Я хочу вернуть все мои Материалы, но также и с конкретным свойством каждого типа. Поэтому я делаю что-то вроде этого:
public List<Material> teste() {
List<Material> materials = business.findAll();
return materials;
}
Мой результат - все материалы, но только с именем и идентификатором. Ни одно из свойств, которые мне нужны, не возвращается. Если я изменю вышеуказанный метод для определенного типа материала, он работает, но я хотел бы получить нечто более общее. Является ли это возможным?
Заранее спасибо!
Это шаблон для класса, содержащего "смешанный список" материалов:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "StoreType", propOrder = {
"mataOrMatb"
})
public class StoreType {
@XmlElements({
@XmlElement(name = "mata", type = MaterialA.class),
@XmlElement(name = "matb", type = MaterialB.class)
})
protected List<Material> mataOrMatb;
public List<Material> getMataOrMatb() {
if (mataOrMatb == null) {
mataOrMatb = new ArrayList<Material>();
}
return this.mataOrMatb;
}
}
Вы можете с радостью вставить объекты MaterialA и MaterialB в список, а маршаллинг должен дать вам:
<store>
<mata>
<name>mata</name
<propertyA1>propa1</propertyA1>
</mata>
<matb>
<name>matb</name>
<propertyB1>propb1</propertyB1>
</matb>
<mata>
<name>mata1</name>
<propertyA1>propa1-1</propertyA1>
</mata>
</store>
Контекст должен содержать каталог (ы), содержащий класс "store" и Material и его подклассы.
Материал класса должен начинаться следующим образом:
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "Material", propOrder = {
"name"
})
@XmlSeeAlso({
MaterialB.class,
MaterialA.class
})
public class Material {
// ...
}
Вы использовали @XmlAccessorType(XmlAccessType.NONE)
в классе, поэтому по умолчанию ваши поля не будут сериализованы/десериализованы.
Или:
Вы должны аннотировать все свойства с помощью @XmlElement
не только для name
.
Или используйте @XmlAccessorType(XmlAccessType.FIELD)
а затем вам не нужно комментировать поля (но вы можете делать исключения с аннотацией @XmlTransient
).
По умолчанию реализация JAXB не будет вызывать подклассы классов при обработке метаданных. Вы можете включать подклассы при создании JAXBContext
, но обычно вы просто используете аннотацию @XmlSeeAlso
в суперклассе, указывая на подклассы, которые вы хотите включить.
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@XmlSeeAlso({MaterialTypeA.class, MaterialTypeB.class})
public abstract class Material {
@XmlElement
не толькоname
. Или используйте@XmlAccessorType(XmlAccessType.FIELD)
и тогда вам не нужно аннотировать поля (но все равно делать исключения с аннотацией@XmlTransient
).