编组从实现与JAXB接口的类实例化的java对象

时间:2014-12-05 14:37:36

标签: java xml eclipse interface jaxb

当我们为类使用接口时,如何使用JAXB将对象编组到XML文件中?我有以下简单的类:

public interface IBook {

    public abstract String getName();

    public abstract void setName(String name);

}
@XmlRootElement
public class Book implements IBook {

    private String name;

    @Override
    @XmlElement(name ="BookTitle")
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }
}


@XmlRootElement
public class BookStore {

    @XmlElement(name ="BookStoreName")
    public String name;

    @XmlElementWrapper(name ="bookList")
    @XmlAnyElement
    public HashSet<IBook> books= new HashSet<IBook>();

    }

当我尝试将BookStore中的对象编组为XML文件时,我收到以下错误:

[com.sun.istack.internal.SAXException2: Weder class de.uni_paderborn.books.Book noch eine der zugehörigen Superklassen ist diesem Kontext bekannt.

javax.xml.bind.JAXBException:Weder class de.uni_paderborn.books.Book noch einederzugehörigenSuperklassenist diesem Kontext bekannt。]

很抱歉德语错误消息,但我的操作系统是德语。这意味着在这种情况下,类Book和其超类都不可知!为什么我会收到这样的错误?

4 个答案:

答案 0 :(得分:2)

问题是您在BookStore类中缺少@XmlSeeAlso。像这样

将它添加到BookStore类
@XmlRootElement
@XmlSeeAlso({Book.class})
public class BookStore {

    @XmlElement(name = "BookStoreName")
    public String name;

    @XmlElementWrapper(name = "bookList")
    @XmlAnyElement
    public HashSet<IBook> books = new HashSet<IBook>();


    public static void main(String[] args) throws JAXBException {
        BookStore bookStore = new BookStore();
        bookStore.name = "FooBookStore";
        Book e = new Book();
        e.setName("Java");
        bookStore.books.add(e);

        /**
         * Create JAXB Context from the classes to be serialized
         */
        JAXBContext context = JAXBContext.newInstance(BookStore.class);
        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        m.marshal(bookStore, System.out);
    }
}

输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bookStore>
    <BookStoreName>FooBookStore</BookStoreName>
    <bookList>
        <book>
            <BookTitle>Java</BookTitle>
        </book>
    </bookList>
</bookStore>

答案 1 :(得分:1)

通常,要映射作为接口类型的字段/属性,请使用type注释上的@XmlElement设置。

@XmlElementWrapper(name ="bookList")
@XmlElement(type=Book.class, name="book")
public HashSet<IBook> books= new HashSet<IBook>();

答案 2 :(得分:0)

我对同一个异常有另一个问题。 我有2个不同的BookStore类,只有包不同: hello.number.one.BookStore hello.number.two.BookStore

我的错误是我用包..in ..填充XML集。但是包含BookStore类包含..two ..因为eclipse包含它对我来说(自动),所以没有注意到错误的BookStore类。 JAXBContext context = JAXBContext.newInstance(BookStore.class);

这很简单,但确实很长时间寻找...希望它能帮到某个地方

答案 3 :(得分:0)

使用spring resp时我遇到了完全相同的问题。添加Jaxb2Marshaller bean。 我有相同的错误消息,因为没有设置

marshaller.setPackagesToScan(...)

正确使用生成文件的正确包名,导致相同的异常。

@Bean(name = "someMarshaller"
Jaxb2Marshaller someMarshaller() {
    final Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setPackagesToScan("my.package.one", "my.package.two");
    return marshaller;
}