2013-04-26 8 views
6

Conosco le basi dell'API JAXB, ma sono bloccato con qualcosa che sto cercando di fare e non sono sicuro che sia effettivamente possibile. I dettagli sono i seguenti:Come eseguire il marshalling di oggetti Java unmarshal con campi privati ​​utilizzando JAXB

ho una classe chiamata Prenota con 2 pubblici variabili di istanza di tipo String:

@XmlRootElement(name="book") 
public class Book 
{ 
    public String title; 
    public String author; 

    public Book() { 
    } 
} 

ho un altro classe chiamata Bookshop con 1 pubblico esempio variabile di tipo ArrayList:

@XmlRootElement(name="bookshop") 
public class Bookshop 
{ 
    @XmlElementWrapper(name="book_list") 
    @XmlElement(name="book") 
    public ArrayList<Book> bookList; 

    public Bookshop() { 
     this.bookList = new ArrayList<>(); 
    } 
} 

Nota: pacchetto la dichiarazione e le importazioni vengono rimosse per risparmiare spazio.

Queste due classi di lavoro e il XML uscita ottengo è qualcosa di simile:

<bookshop> 
    <book_list> 
     <book> 
      <title>Book 1</title> 
      <author>Author 1</author> 
     </book> 
     <book> 
      <title>Book 2</title> 
      <author>Author 2</author> 
     </book> 
    </book_list> 
</bookshop> 

Per quanto ne so, le variabili di istanza devono essere dichiarate pubblico al fine per la sua classe di essere serialisable. Oppure, le variabili di istanza possono essere dichiarate private, ma in questo caso sono necessari accessor e mutator.

Non mi piace dichiarare pubbliche le variabili di istanza; Mi piace usare accessors e mutator. Anche allora, voglio che alcuni dei miei campi siano di sola lettura, cioè nessun mutatore. Ma JAXB sembra richiedere sia gli accessori che i mutatori per ogni campo che vuoi maresciallo/unmarsale. Mi stavo chiedendo se c'è un modo per aggirare questo?

+2

non jaxb usa la riflessione? – Jayan

+1

Guardando questa domanda http://stackoverflow.com/questions/3391256/how-java-jaxb-works, dovrebbe funzionare bene solo con i campi privati ​​ – Jayan

+0

Sì, utilizza la riflessione; forse ho bisogno di aggiungere attributo XML a ogni campo di istanza (pubblico, privato o protetto) – temelm

risposta

5

Si dovrebbe tenere i campi privato in ogni caso. Hai 2 opzioni di rilegatura a campi

1) annotare i vostri campi con XmlElement o XmlAttribute annotazione

@XmlRootElement(name="book") 
public class Book { 
    @XmlElement 
    private String title; 
    ... 

2) annotare la classe con @XmlAccessorType (XmlAccessType.FIELD)

@XmlRootElement(name="book") 
    @XmlAccessorType(XmlAccessType.FIELD) 
    public class Book { 
     private String title; 
     ... 
+0

Lo proverò. – temelm

+0

Questo in effetti funziona sia per il marshalling che per l'unmarshalling, l'unica cosa che dovevo fare era aggiungere "@XmlElement" sopra le dichiarazioni delle variabili di istanza. Molte grazie! – temelm

+0

@temelm - Se si specifica '@XmlAcessorType (XmlAccessType.FIELD)' non sarà necessario inserire '@ XmlElement' sul campo. Se si sceglie il tipo di accesso predefinito e si annota il campo, ricordare che la combinazione get/set corrispondente verrà mappata per impostazione predefinita. –

-3

JAXB avrà bisogno di entrambi: - Un'istanza pubblico variabile o - Una variabile di istanza privato con mutators pubblici e di accesso.

Sarà necessario mutators di riunire e acessors per unmarshalling

+0

Non si interrompe se non ci sono mutatori ma i valori per questi campi diventano "null". Quindi i mutatori sono un must? – temelm

+0

Sono, infatti. Pensala come un oggetto e dimentica di JAXB. Come modificherai una variabile di istanza contrassegnata come privata senza un mutatore (a livello di codice o di riflessione se era JAXB ad accedervi) – javadev

+0

ciò che dici ha senso, ma ho pensato che l'intero punto di JAXB fosse la possibilità di eseguire una semplice serializzazione XML/deserializzazione, non importa quale sia il nostro modello; e come Evgeniy Dorofeev ha sottolineato, questo è effettivamente possibile. – temelm