Java в XML Аннотация для наследования

1

Я не нашел подобной проблемы, поэтому я понятия не имею, возможно ли это или нет.

У меня есть пара классов с одинаковым наследованием. Мой основной класс - 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;
}

Мой результат - все материалы, но только с именем и идентификатором. Ни одно из свойств, которые мне нужны, не возвращается. Если я изменю вышеуказанный метод для определенного типа материала, он работает, но я хотел бы получить нечто более общее. Является ли это возможным?

Заранее спасибо!

  • 1
    Вы должны аннотировать все свойства @XmlElement не только name . Или используйте @XmlAccessorType(XmlAccessType.FIELD) и тогда вам не нужно аннотировать поля (но все равно делать исключения с аннотацией @XmlTransient ).
  • 0
    Как говорит @icza, потому что вы использовали XmlAccessType.NONE.
Показать ещё 1 комментарий
Теги:
inheritance
jaxb

3 ответа

1
Лучший ответ

Это шаблон для класса, содержащего "смешанный список" материалов:

@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 {
    // ...
}
  • 0
    Использование @XmlSeeAlso также решило проблему. Большое спасибо.
2

Вы использовали @XmlAccessorType(XmlAccessType.NONE) в классе, поэтому по умолчанию ваши поля не будут сериализованы/десериализованы.

Или:

  • Вы должны аннотировать все свойства с помощью @XmlElement не только для name.

  • Или используйте @XmlAccessorType(XmlAccessType.FIELD) а затем вам не нужно комментировать поля (но вы можете делать исключения с аннотацией @XmlTransient).

  • 0
    Как я уже сказал в предыдущем комментарии.
  • 1
    @icza Вы не решаете настоящую проблему.
1

По умолчанию реализация JAXB не будет вызывать подклассы классов при обработке метаданных. Вы можете включать подклассы при создании JAXBContext, но обычно вы просто используете аннотацию @XmlSeeAlso в суперклассе, указывая на подклассы, которые вы хотите включить.

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@XmlSeeAlso({MaterialTypeA.class, MaterialTypeB.class})
public abstract class Material {
  • 0
    @XmlSeeAlso решил проблему, но как только отвечал лаун, я принял его как правильный ответ. Но все равно спасибо!
  • 0
    @ kneves.vinicius - Чтобы быть справедливым, согласно отметке времени я ответил за 4 часа до запуска :)
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню