2014-12-05 135 views
3

当我们为类使用接口时,如何使用JAXB将对象封送到XML文件中?我有以下简单的类:从实现与JAXB接口的类实例化封送Java对象

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>(); 

    } 

,当我试图从元帅的书店对象到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 eine derzugehörigenSuperklassen ist diesem Kontext bekannt。]

对不起德国错误信息,但我的操作系统是德语。这意味着在这种情况下,Book类和其中的一个超类都是已知的!为什么我会得到这样的错误?

+0

您可能会发现以下内容有用:http://blog.bdoughan.com/2011/05/jaxb-and-interface-fronted-models.html。另外,我很好奇为什么你在'books'字段上使用'@ XmlAnyElement'。 – 2014-12-05 15:42:13

+0

因为没有它,我得到另一个错误,告诉我试图编组一个接口,因为书'HashSet'中的元素来自'IBook',而不是'Book'。谢谢! – Anas 2014-12-05 15:53:09

+0

我已经添加了一个应该可以帮助的答案:http://stackoverflow.com/a/27319803/383861 – 2014-12-05 15:55:31

回答

1

一般映射字段/属性是一个接口类型您使用的@XmlElement注解type设置。

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

好的,谢谢!它与以前的答案类似,但是我应该再次提到可能会进入我的'HashSet 书籍'中的每个课程? – Anas 2014-12-05 15:58:54

+0

@Anas你有不同的impls可以进去吗? – 2014-12-05 16:00:26

+0

是的,他们可以来自不同的impls – Anas 2014-12-05 16:02:19

2

问题是您在BookStore类中缺少@XmlSeeAlso。将它添加到您的图书城类这样

@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> 
+0

我应该为每个类型添加这个“@ XmlSeeAlso”吗?谢谢! – Anas 2014-12-05 15:54:21

+0

是的,如果他们不同impls – sol4me 2014-12-05 16:10:30

0

我对于同样的例外有另一个问题。 我有2个不同的图书城班只有包不同: hello.number.one.BookStore hello.number.two.BookStore

我的错误是我被灌了XML与包..one设置..但包括包含..two的BookStore类..因为eclipse包含它对我来说(自动),所以没有注意到错误的BookStore类。 JAXBContext context = JAXBContext.newInstance(BookStore.class);

很简单,但很长搜索确实...希望它有助于地方

0

我有完全相同的问题与春天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; 
}