Java JAXB, как переопределить XmlElements к существующей переменной - PullRequest
4 голосов
/ 03 марта 2010

При демонтаже с использованием jaxb у меня в классе A что-то не так:

public class A {
    @XmlElements( { //
    @XmlElement(name = "g", type = A.class),
        @XmlElement(name = "x", type = X.class), 
        @XmlElement(name = "y", type = Y.class),        
    })
    List<XXX> children;
}

То есть у меня есть список детей, состоящий из X: s и Y: s

Теперь на мой вопрос: я хотел бы подкласс А, и я хотел бы переопределить список 'XmlElements' и связать его с той же переменной, 'children', как:

public class B extends A {
    @XmlElements( { //
    @XmlElement(name = "g", type = B.class),
        @XmlElement(name = "x", type = X.class), 
        @XmlElement(name = "y", type = Y.class), 
        @XmlElement(name = "z", type = Z.class),        
    })
    List<XXX> children;
}

Проблемы, связанные с вышесказанным, имеют две стороны:

  1. Я создаю новую переменную потомков, я хотел бы сослаться на переменную в классе A.

  2. Я бы хотел избежать повторного указания «x» и «y», поскольку они уже указаны в «A».

Есть ли хороший пример для достижения этой цели?

Или несколько указателей / статей или другой информации о том, как создать что-то подобное?

Ответы [ 2 ]

2 голосов
/ 03 марта 2010

Нельзя избежать повторного объявления аннотации, но вы можете переместить аннотацию из поля в метод получения, если вы используете аннотацию @XmlAccessorType, чтобы JAXB посмотрел для общедоступных методов получения, а не для полей.

Чтобы вы могли переопределить getChildren() в классе B с новым набором аннотаций:

@XmlAccessorType(PROPERTY)
public class A {
    private List<XXX> children;

    @XmlElements( { //
    @XmlElement(name = "g", type = A.class),
        @XmlElement(name = "x", type = X.class), 
        @XmlElement(name = "y", type = Y.class),        
    })
    public List<XXX> getChildren() {
       return children;
    }

    public void setChildren(List<XXX> children) {
       this.children = children;
    }
}

@XmlAccessorType(PROPERTY)
public class B extends A {
    @XmlElements( { //
    @XmlElement(name = "g", type = B.class),
        @XmlElement(name = "x", type = X.class), 
        @XmlElement(name = "y", type = Y.class), 
        @XmlElement(name = "z", type = Z.class),        
    })
    public List<XXX> getChildren() {
       return super.getChildren();
    }
}

В чем я не уверен, так это в том, как JAXB будет обрабатывать переопределенный метод getChildren(). Надеюсь, он примет аннотации от B, но, возможно, он запутается.

Попробуй и посмотри.

1 голос
/ 27 сентября 2010

JAXB будет фактически обрабатывать переопределенный метод, когда PROPERTY @XmlAccessorType используется в parent, но в результате в выходных данных xml JAXB, вероятно, также будет генерировать дополнительно в атрибутах корневого тега, таких как: xsi: type = " B "и xmlns: xsi =" http://www.w3.org/2001/XMLSchema-instance",, потому что мы определили новый тип B, унаследованный от A. Таким образом, xml, созданный из класса A, не будет идентичен произведенному из класса B из-за этих двух атрибутов, правильно добавленных JAXB для информирования что мы определили дополнительный тип B.

Я хотел бы увидеть способ избежать этой xsi и xmlns информации в выходном xml. Такое поведение JAXB совершенно нормально, но для меня было бы замечательно не сообщить получателю в моем выводе xml, что я создал класс, расширяющий исходный класс, который я, возможно, взял из клиентской xsd-схемы.

Чтобы создать xml из производного подкласса, но без атрибутов xsi и xmlns , добавленных JAXB, я использовал временную уловку, которую я пытаюсь обменять на что-то более приятное: я переопределил метода в child, в методе родительского переопределения мне пришлось использовать @XmlElement, но я не добавил наследуемый тип класса в вызов JAXB.newinstance.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...