Katalog książek – cz. 2
Transkrypt
Katalog książek – cz. 2
Integracja aplikacji Ćwiczenie 4 Katalog książek – cz. 2 Odczytywanie danych z XML Do ćwiczenia dołączony jest plik books.xml zawierający pełen katalog książek. Poniższy listing zawiera przykładowy fragment danych w stosowanym formacie. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <books> <book id="1"> <author>Brett D. McLaughlin, Justin Edelson</author> <isbn>978-83-246-6075-9</isbn> <pages>0</pages> <publisher>Helion</publisher> <title>Java i XML. Wydanie III</title> <year>2007</year> </book> <book id="2"> <author>Testowy autor</author> <isbn>123-45-678-9012-3</isbn> <pages>0</pages> <publisher>Helion</publisher> <title>Testowy tytuł</title> <year>2007</year> </book> </books> W kolejnych krokach rozbudujemy kod z ćwiczenia 1 o odczytywanie książek z pliku XML z użyciem standardu JAXB. 1) Otwórz projekt z ćwiczenia nr 1. Do katalogu projektu skopiuj plik books.xml dołączony do ćwiczenia. 2) Uzupełnij klasę Book o odpowiednie adnotacje: @XmlType(name = "book") Adnotację XmlType umieść przed nagłówkiem klasy Book. Informuje ona biblioteki JAXB o tym, że klasa Book będzie odpowiadać typowi o nazwie „book” w dokumencie XML. @XmlAttribute Adnotację XmlAttribute umieść przed metodą getId(). Informuje ona o tym, że właściwość „id” ma zostać zmapowana w sposób inny, niż domyślny – na atrybut XML (domyślnie zostałaby zmapowana na element o nazwie „id”). Strona 1 Integracja aplikacji Ćwiczenie 4 3) Stwórz klasę BookList, zawierającą listę książek oraz spełniającą wymagania JavaBean: package books; import java.util.List; public class BookList { private List<Book> books; public List<Book> getBooks() { return books; } public void setBooks(List<Book> books) { this.books = books; } } Uzupełnij klasę o odpowiednie adnotacje: @XmlRootElement(name = "books") przed nagłówkiem klasy @XmlElement(name = "book") przed metodą getBooks() Po uzupełnieniu pełny kod klasy BookList powinien wyglądać następująco: package books; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "books") public class BookList { private List<Book> books; @XmlElement(name = "book") public List<Book> getBooks() { return books; } public void setBooks(List<Book> books) { this.books = books; } } Strona 2 Integracja aplikacji Ćwiczenie 4 4) Zmień kod metody main() w klasie Main, tak żeby odczytywał listę książek z pliku books.xml. Poniższe dwa listingi przedstawiają sam kod do odczytania danych z pliku XML z użyciem JAXB, a następnie całą metodę main(), po wymaganych uzupełnieniach i modyfikacjach. Odczyt listy książek z pliku XML: try { JAXBContext context = JAXBContext.newInstance(BookList.class); Unmarshaller um = context.createUnmarshaller(); FileReader fr = new FileReader("books.xml"); BookList bl = (BookList) um.unmarshal(fr); fr.close(); } catch (JAXBException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Cała metoda main() po wszystkich modyfikacjach: public static void main(String[] args) { try { JAXBContext context = JAXBContext.newInstance(BookList.class); Unmarshaller um = context.createUnmarshaller(); FileReader file = new FileReader("books.xml"); BookList books = (BookList)um.unmarshal(file); file.close(); BookManager bm = new BookManager( books.getBooks() ); List<Book> bs = bm.searchByTitle("Java"); System.out.println(bs); } catch (Exception ex) { ex.printStackTrace(); } } Strona 3 Integracja aplikacji Ćwiczenie 4 Zadanie 1 Zapis danych do XML odbywa się bardzo podobnie, jak odczyt. Aby zapisać pewien obiekt do XML, należy: przygotować kontekst JAXB (jak w powyższym kodzie); przygotować obiekt serializujący (zwany w JAXB „marshallerem”), wywołując metodę createMarshaller(); wywołać metodę marshal(), przekazując do niej obiekt do zapisania oraz plik lub strumień wyjściowy. Klasa, do której należy zapisywany obiekt, musi posiadać odpowiednie adnotacje JAXB, w tym adnotację XmlRootElement. W naszym projekcie bezpośrednio zapisywać można obiekty klasy BookList. Dopisz do metody main() kod realizujący następujące zadanie: stwórz nową książkę; jako autora podaj swoje imię i nazwisko, jako tytuł „Laboratorium: Java i XML”; dodaj tę książkę do listy w utworzonym wcześniej obiekcie BookManager; wyszukaj książki ze słowem Java w tytule; wynik „opakuj” w klasę BookList (czyli utwórz nowy obiekt klasy BookList, metodą setBooks() zapisz w nim listę znalezionych książek); zapisz powstałą listę książek do nowego pliku XML o nazwie lab3.xml. Zadanie 2 Zrób kopię projektu – pierwotną wersję zachowaj na potrzeby kolejnych zajęć; kopii użyj w bieżącym zadaniu. Przyjrzyj się różnicy pomiędzy plikami books.xml i books.2.xml – w pierwszym przypadku autorzy książki są podani w jednym elemencie XML, po przecinku: <author>Jan Kowalski, Jan Nowak</author> w drugim pliku autorzy są rozbici na osobne elementy: <authors> <author>Jan Kowalski</author> <author>Jan Nowak</author> </authors> Strona 4 Integracja aplikacji Ćwiczenie 4 Zmodyfikuj klasę Book tak, aby była zgodna z drugą wersją (plik books.2.xml): o zamiast pola String author umieść pole: List<String> authors o usuń meotdy getAuthor() i setAuthor(), zastąp je odpowiednimi metodami getAuthors() i setAuthors() (skutkiem ubocznym będą błędy kompilacji w klasie BookManager – dla uproszczenia możesz usunąć z klasy BookManager kod wyszukujący książki po autorze); o do poprawnej serializacji/deserializacji autorów konieczne będzie użycie adnotacji @XmlElementWrapper – przykład jej użycia znajdziesz m.in. tutaj: https://jaxb.java.net/tutorial/section_6_2_7_7-Wrapping-Repeated-ElementsXmlElementWrapper.html Zadanie 3 W pliku books.3.xml znajdziesz kolejną wersję formatu XML. Tym razem element publisher jest elementem złożonym, zawiera zagnieżdżone elementy name i url. Zmodyfikuj kod programu tak, by możliwe było odczytanie nowego formatu pliku. Konieczne będzie stworzenie klasy Publisher i odpowiednie zmapowanie jej do XML. Zadanie dodatkowe Przygotuj analogiczny kod dla danych przygotowanych w ramach poprzedniego ćwiczenia (własny plik XML i schemat XML Schema). Strona 5