Zakładamy, że utworzony programowo dokument został zapisany w postaci pliku HTML. Co jednak, gdybyśmy chcieli mieć możliwość zapisu i późniejszego odczytu zawartości dokumentu?
Jednym z wygodnych rozwiązań jest zastosowanie JAXB (Java Architecture for XML Binding), biblioteki pozwalającej na zapis złożonej struktury obiektów w pamięci w formacie XML (ang. marshal) i późniejsze odtworzenie struktury obiektów z dokumentu XML (ang. unmarshal).
Aby zapis i odczyt był mozliwy musi być spełnionych kilka warunków:
Dla przypomnienia <to:jest:tag att=“a to jest atrybut”> a tag zamykający wygląda tak </to:jest:tag>.
Biblioteka JAXB używa specyficznego mechanizmu języka - adnotacji (ang. annotations) [który chyba nie będzie omawiany na wykładzie ???]
Adnotacje mają postać @Identifier lub @Identifier(key=value[,otherkey=othervalue]) i są umieszczane w kodzie programu, zazwyczaj przed definicją klasy, deklaracją atrybutu lub definicją metody.
Na przykład:
<code java>
@Override
public String toString(){
return "";
}
</code>
Adnotacje nie mają bezpośredniego wpływu na wykonanie kodu, ale mogą być wykorzystywane przez zewnętrzne narzędzia przetwarzające kod (zarówno źródłowy, jak i skompilowany):
@org.junit.Test Formalnie, adnotacje deklaruje się jak interfejsy i umieszcza w pakietach
Dodając adnotacje zadbaj, aby importować elementy z pakietu javax.xml.bind.annotation
Dodaj w klasie Document metody do zapisu i odczytu
<code java>
public void write(String fileName){
try {
JAXBContext jc = JAXBContext.newInstance(Document.class);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
FileWriter writer= new FileWriter(fileName);;
m.marshal(this, writer);
} catch (JAXBException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
public static Document read(String fileName){
try {
JAXBContext jc = JAXBContext.newInstance(Document.class);
Unmarshaller m = jc.createUnmarshaller();
FileReader reader = new FileReader(fileName);
return (Document) m.unmarshal(reader);
} catch (JAXBException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
</code>
Dodaj także w funkcji main() kod, który zapisuje (i odczytuje) dokument
<code java>
cv.write("cv.xml");
//Document cv2 = Document.read("cv.xml");
//cv2.writeHTML(System.out);
</code>
Java SE 9 nie widzi części modułów Java EE, w tym JAXB.
1. W IntelliJ w dialogu Project Structure - ustaw Project language Level : 8 - lambdas, type annotations
2. Zalecanym obejściem (w https://blog.codefx.org/java/java-9-migration-guide/) jest dodanie opcji uruchamiania programu
<code> –add-modules java.se.ee </code>
W IntelliJ nalezy je wpisac w oknie Run → Edit Configurations → pole VM options
W następnych etapach będziemy modyfikowali kod (dodawali adnotacje) i sprawdzali, co zmienia się w pliku cv.xml
Najczęściej używane będą następujące adnotacje
@XmlRootElement - oznaczenie klasy będącej korzeniem drzewa XML @XmlElement - oznaczenie, że atrybut ma zostać zapisany jako element XML (jako nazwa znacznika XML zostanie użyta nazwa atrybutu) @XmlElement(name=“xyz”) - podana jest nazwa znacznika xyz XmlAttribute atrybut (pole klasy) zostanie zapisany jako atrybut XML <code java> @XmlRootElement public class Document { … } </code>
Zobacz, co zostało zapisane do pliku cv.xml
<code java>
@XmlElement String title; @XmlElement List<Section> sections = new ArrayList<>(); @XmlElement Photo photo;
</code>
Wykonaj program i spróbuj zidentyfikować i naprawić błąd…
Pole url odwzorujemy w atrybut
<code java>
@XmlAttribute String url;
</code>
Tytuł jest zapewne krótki - odwzorujemy go w atrybut, natomiast listę akapitów (paragraphs) w XmlElement
Zastąp w odpowiednim miejscu @XmlElement przez @XmlElement(name=“section”) i @XmlElement(name=“paragraph”).
1. Uzupełnijmy więc znaczniki w ParagraphWithList, UnorderedList oraz ListItem
Prawdopodobnie dalej lista w cv.xml nie będzie widoczna…
2. Poinformuj, JAXB o klasach potomnych Paragraph
<code java> @XmlSeeAlso({ParagraphWithList.class}) public class Paragraph { </code>
… i usuń ewentualne błędy.
3. Możesz przyjrzeć się znacznikom i poprawić nazwy według uznania