Как сказать JAXB игнорировать свойства родительского класса - PullRequest
4 голосов
/ 15 февраля 2012

Я сталкиваюсь со следующими проблемами с JAXB: похоже, JAXB анализирует свойства от самого глубокого дочернего класса к родительскому, а дочернее свойство имеет приоритет.Я хотел бы как-то изменить это поведение.В частности:

Дочерний класс:

package test.sub;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;


@XmlAccessorType(XmlAccessType.NONE)
public class BasicDocument {

    private String comment;

    public String getComment() {
        return comment;
    }

    public void setComment(String cost) {
        this.comment = cost;
    }
}

Родительский класс:

package test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import test.sub.BasicDocument;

@XmlRootElement(name="Description", namespace="http://www.w3.org/1999/02/22-rdf-syntax-ns#")
@XmlAccessorType(XmlAccessType.PROPERTY)
class Document extends BasicDocument {

    private String identifier;

    @XmlElement(name = "identifier", namespace = "http://purl.org/dc/terms/")
    public String getIdentifier() {
        return identifier;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }

    @Override
    @XmlElement(name = "abstract", namespace = "http://purl.org/dc/terms/")
    public String getComment() {
        return super.getComment();
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

Прекрасно работает Marshalling:

Document document = new Document();

document.setIdentifier("12A");
document.setComment("special");

StringWriter w = new StringWriter();

jaxbContext.createMarshaller().marshal(document, new StreamResult(w));

System.out.println(w);

Вывод:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Description xmlns:ns2="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/dc/terms/">
    <abstract>special</abstract>
    <identifier>12A</identifier>
</ns2:Description>

Но сортировка игнорирует свойство, которое находится в дочернем BasicDocument классе (t.xml в точности соответствует приведенному выше XML):

JAXBContext jaxbContext = JAXBContext.newInstance(Document.class);

Document document = (Document) jaxbContext.createUnmarshaller().unmarshal(Document.class.getResourceAsStream("t.xml"));

System.out.println("out: " + document);

Вывод:

out: Document[identifier=12A,comment=<null>]

Ожидается:

out: Document[identifier=12A,comment=special]

В основном @XmlAccessorType(XmlAccessType.NONE) на BasicDocument (см. Игнорировать родительский класс при сериализации в XML ) не имеет никакого эффекта.Также создание package-info.java в пакете test.sub (см. @ XmlTransient на стороннем или внешнем суперклассе ) следующим образом:

@XmlAccessorType(XmlAccessType.NONE)
package test.sub;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

не оказало никакого эффекта.Работало только @XmlTransient public class BasicDocument.В идеале я не хотел бы добавлять какие-либо аннотации на child и контролировать это поведение только с помощью package-info.java.Как я могу это сделать?

Протестировано на JDK 1.6.0_27 и дополнительно с JAXB 2.2.4-1 во время выполнения в classpath.

Это функция или ошибка?

1 Ответ

2 голосов
/ 15 февраля 2012

Вам просто нужно добавить метод setComment в класс Document.Без него оно обрабатывается как свойство только для записи, даже если метод существует в родительском классе.

public void setComment(String comment) {
    super.setComment(comment);
}

Полный источник для Document

package test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import test.sub.BasicDocument;

@XmlRootElement(name="Description", namespace="http://www.w3.org/1999/02/22-rdf-syntax-ns#")
@XmlAccessorType(XmlAccessType.PROPERTY)
class Document extends BasicDocument {

    private String identifier;

    @XmlElement(name = "identifier", namespace = "http://purl.org/dc/terms/")
    public String getIdentifier() {
        return identifier;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }

    @Override
    @XmlElement(name = "abstract", namespace = "http://purl.org/dc/terms/")
    public String getComment() {
        return super.getComment();
    }

    public void setComment(String comment) {
        super.setComment(comment);
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

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