2013-04-26 14 views
6

Znam podstawy API JAXB, ale utknąłem z czymś, co próbuję zrobić, i nie jestem pewien, czy jest to rzeczywiście możliwe. Szczegóły są następujące:Jak marnować/unmarshal obiektów Java z prywatnymi polami za pomocą JAXB

Mam klasy o nazwie Book z 2 publicznych instancji zmiennych typu String:

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

    public Book() { 
    } 
} 

mam inna klasa nazywa Bookshop z 1 publicznej instancji zmienna typu ArrayList:

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

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

Uwaga: pakiet deklaracja i import są usuwane w celu zaoszczędzenia miejsca.

Te dwie klasy pracy i XML wyjście otrzymuję jest coś takiego:

<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> 

O ile mi wiadomo, zmienne instancji muszą być deklarowane publicznej w celu jej klasa będzie serialisable. Innymi słowy zmienne instancji mogą być zadeklarowane jako prywatne, ale w tym przypadku potrzebne są akcesory i mutatory.

Nie lubię zadeklarować zmiennych instancji publicznych; Lubię używać akcesorów i mutatorów. Nawet wtedy chcę, aby niektóre z moich pól były tylko do odczytu, tj. Bez mutatora. Ale wydaje się, że JAXB wymaga zarówno akcesorów, jak i mutatorów dla każdego pola, które ma być marszałkiem/unmarshal. Zastanawiałem się, czy jest jakiś sposób obejścia tego?

+2

nie działa jaxb używać refleksji? – Jayan

+1

Patrząc na to pytanie http://stackoverflow.com/questions/3391256/how-java-jaxb-works, powinno to po prostu działać dobrze z prywatnymi polami – Jayan

+0

Tak, używa refleksji; może muszę dodać atrybut XML do każdego pola instancji (publicznego, prywatnego lub chronionego) – temelm

Odpowiedz

5

Należy zachować pól prywatnych w każdym przypadku. Masz 2 opcje wiązania z pól

1) opisywanie swoich pól z XmlElement lub XmlAttribute adnotacji

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

2) adnotacje swoją klasę z @XmlAccessorType (XmlAccessType.FIELD)

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

Spróbuję tego. – temelm

+0

To naprawdę działa zarówno przy rozstawianiu jak i likwidowaniu, jedyne, co musiałem zrobić, to dodać "@XmlElement" nad deklaracjami zmiennych instancji. Wielkie dzięki! – temelm

+0

@temelm - Jeśli podasz '@XmlAcessorType (XmlAccessType.FIELD)' nie będziesz musiał wstawiać '@ XmlElement' na polu. Jeśli wybierzesz domyślny typ akcesorium i dodasz adnotację do pola pamiętaj, że odpowiednia kombinacja get/set będzie również domyślnie mapowana. –

-3

JAXB będzie potrzebował: - Publiczna zmienna instancji Lub - Prywatna instancja zmienna z publicznymi mutatorami i akcesorami.

Musisz mutatorów dla zestawiania i acessors dla unmarshalling

+0

Nie łamie się, jeśli nie ma mutatorów, ale wartości dla tych pól stają się "puste". Więc mutatorzy są koniecznością? – temelm

+0

Są one rzeczywiście. Pomyśl o tym jako o Objectie i zapomnij o JAXB. W jaki sposób zmodyfikujesz zmienną instancji oznaczoną jako prywatną bez mutatora (programowo lub przez odbicie, jeśli był to JAXB, który uzyskuje do niej dostęp)? – javadev

+0

to, co mówisz, ma sens, ale myślałem, że cały punkt JAXB będzie mógł wykonywać prostą serializację XML/deserializacja bez względu na nasz model; a jak zauważył Evgeniy Dorofeev, jest to możliwe. – temelm