2014-12-05 65 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; 
}