Passa ai contenuti principali

JAXB - Il supporto di Java all'XML



Introduzione
Ho fatto una sintesi dell'ottimo articolo di Marco Parente che approfondisce perfettamente JAXB.

JAXB
"Java Architecture for XML Binding" è un framework di supporto di XML per Java.
Dalla versione 1.6 di Java SE il framework JAXB è incluso e fornisce una serie di API completa per la gestione dei documenti XML.

Le applicazioni più comuni di XML+Java sono SAX (Simple API for XML) e DOM (Document Object Model) e appartengono entrambe al pacchetto JAXP (Java API for XML Processing) che vengono utilizzate per effettuare l'analisi dei documenti XML.

SAX non salva nulla in memoria e il documento viene letto dall'inizio alla fine. Quindi non sono disponibili in queste API operazioni  che richiedono la memorizzazione del documento o parti di esso.

DOM memorizza l'intero documento in memoria e quindi sono messi a disposizione strumenti per analizzare e/o modificare i dati.

JAXB fornisce una astrazione tale che non richiede la conoscenza del contenuto dell'XML. Tutto questo grazie a tre operazioni principali:

- Binding
- Unmarshalling
- Marshalling

Per illustrare gli strumenti messi a disposizione da JAXB si costruirà il seguente progetto:







Binding
Questa operazione è rivolta all'accesso al documento e consiste nella generazione di una serie di classi Java che rappresentano lo schema che si vuole accedere e la creazione delle classi, istanza dello schema definito, mediante un apposito compilatore che si chiama "xjc".

Nelle cartelle All e Schemi definiamo i file xsd che descrivono il nostro schema di esempio, quello di una pianta che richiama altri schemi definiti sotto:

Pianta.xsd


<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema
  xmlns:sc2="http://www.flora.bindings.com"
  xmlns:sc1="http://www.elementiBase.bindings.com"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.flora.bindings.com">
<xs:import namespace="http://www.elementiBase.bindings.com" schemaLocation="../Schemi/Radice.xsd" />
<xs:import namespace="http://www.elementiBase.bindings.com" schemaLocation="../Schemi/Fusto.xsd" />
<xs:import namespace="http://www.elementiBase.bindings.com" schemaLocation="../Schemi/Foglia.xsd" />
<xs:element name="Pianta">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Nome" element="xs:string" />
      <xs:element ref="sc1:TipologiaRadice" />
      <xs:element ref="sc1:CaratteristicheFusto" />
      <xs:element ref="sc1:CaratteristicheFoglie" />  
    </xs:sequence>
  </xs:complexType>
</xs:element>
</xs:schema>



Radice.xsd



<?xml version="1.0" encoding="ISO-8859-1" ?> <xs:schema  xmlns:sc1="http://www.elementiBase.bindings.com"  xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="http://www.elementiBase.bindings.com"><xs:import namespace="http://www.w3.org/2001/XMLSchema" /><xs:element name="TipologiaRadice">  <xs:complexType>    <xs:sequence>      <xs:element name="Ramificazione" type="xs:string" />      <xs:element name="Resistenza" type="xs:string" />    </xs:sequence>  </xs:complexType></xs:element></xs:schema>


Fusto.xsd



<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema
  xmlns:sc1="http://www.elementiBase.bindings.com"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.elementiBase.bindings.com">
<xs:import namespace="http://www.w3.org/2001/XMLSchema" />
<xs:element name="CaratteristicheFusto">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Tipo" type="xs:string" />
      <xs:element name="Spessore" type="xs:int" />
      <xs:element name="Altezza" type="xs:int" />
    </xs:sequence>
  </xs:complexType>
</xs:element>
</xs:schema>



Foglia.xsd



<?xml version="1.0" encoding="ISO-8859-1" ?> <xs:schema  xmlns:sc1="http://www.elementiBase.bindings.com"  xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="http://www.elementiBase.bindings.com"><xs:import namespace="http://www.w3.org/2001/XMLSchema" /><xs:element name="CaratteristicheFoglie">  <xs:complexType>    <xs:sequence>      <xs:element name="Tipo" type="xs:string" />            <xs:element name="Forma" type="xs:string" />    </xs:sequence>  </xs:complexType></xs:element></xs:schema>


Dagli schemi si passa alla produzione delle classi grazie all'utilitàxjc da lanciare semplicemente posizionandosi con la shell a riga di comando nella cartella "All": 

xjc -nv Pianta.xsd

Verranno generate tutte le classi usate da Pianta nel rispetto del namespace definito che conterranno i metodi get e set in perfetto stile java beans.
Il mapping tra XML e Java viene implementato mediante delle annotazioni. Per ogni package vengono definite due classi:

package-info.java : è il descrittore del package con la responsabilità di importare le librerie contenenti le annotazioni JAXB

ObjectFactory.java : consente di creare oggetti a run-time in seguito ad azioni dell'utente o del flusso di informazioni.


Unmarshalling
Effettuare l'Unmarshalling di un documento XML significa creare un albero di oggetti che rappresenta il contenuto e l'organizzazione del documento.
Per effettuare l'unmarshalling occorre istanziare un oggetto JAXBContext, un oggetto Unmarshaller e invocare il metodo.

JAXBContext : fornisce l'entry point per le API specificando una lista di uno o più nomi di package che contengono le interfacce generate da un binding compiler.

Unmarshaller: controlla il processo di unmarshalling del documento XML passato sotto forma di file. Ciò che viene restituito è un oggetto che può essere castato.


Sotto il pezzo di codice che invoca il metodo, istruendolo, e restituisce l'oggetto castato.


...
static String filePath = "xmlExample/pianta.xml"; 
static String context = "com.bindings.flora";  
static JaxbUnmarshal unmarshall = new JaxbUnmarshal(filePath, context); 
static Pianta piantaObj = (Pianta) unmarshall.getUnmarshalledObject();
...

Il casting consente di tenere la classe JaxbUnmarshal rimane generica.
Se si volesse accedere ai dati del file XML senza farne l'unmarshalling è possibile utilizzare i metodi set degli oggetti ObjectFactory generati dal compilatore.



...Pianta nuovapianta = new Pianta();nuovapianta.setNome("Alloro");      CaratteristicheFusto fustoAlloro = new CaratteristicheFusto();fustoAlloro.setSpessore(1);fustoAlloro.setAltezza(8);nuovapianta.setCaratteristicheFusto(fustoAlloro);...


Interessante notare la disponibilità del metodo setValidating() della classe Unmarshaller. Licenza Creative Commons
Quest'opera è distribuita con Licenza Creative Commons Attribuzione - Condividi allo stesso modo 4.0 Internazionale.

Commenti

Post popolari in questo blog

Telecamere Ip con accesso "nascosto"

Telecamere Ip con accesso "nascosto" Storia triste di un auto-hacking obbligato che mi ha fatto scoprire come la nostra privacy è realmente messa a rischi. Storia Ho acquistato dal mercatino/fiera del Radioamatore di Fasano quattro telecamere IP. La scatola riporta "Smart Camera" LF4810. Ne ho montata una e testata in tutte le sue funzionalità per oltre un mese. Chiaramente la manualistica scarsissima, come da tradizione in questi prodotti cinesi di costo molto concorrenziale, consiste in un "pieghevole" di 4 facciate. Chiaramente non erano documentate le impostazioni necessarie per attivare i protocolli ONVIF e RTSP che mi sono indispensabili per l'uso che ne devo fare. Nonostante questa scarsa documentazione dopo l'installazione base fatta con l'apposita app: tutto sembrava corretto. Chiaramente la prima azione che ho compiuto è stata quella di cambiare la password che di default è "123". Subito dopo h...

Dynamic DNS con Duckdns.org in HTTPS

Obiettivo Avere un dominio https con certificato valido da usare come endpoint pubblico per Homeassistant e per un WebHook per i bot telegram. Fase 1 Registrazione del dominio in un servizio di dynamic DNS come https://www.duckdns.org/   : Scegliere per quale sistema operativo installare il client che si occuperà dell'aggiornamento dell'ip: Seguire la semplice guida per la configurazione del processo cron: Fase 2 Creazione del certificato e installazione sul server. Di tutto questo si occuperà una applicazione che si chiama certbot. $ sudo add-apt-repository ppa:certbot/certbot $ sudo apt install python-certbot-apache $ sudo certbot --apache -d ol3.duckdns.org -d www.ol3.duckdns.org Fase 3 Esporre il servizio https sulla rete pubblica. Aprire o reindirizzare la porta 443 verso l'host sul quale si è fatta la configurazione di certbot dal proprio router. Il certificato di certbot è valido per novanta giorn...

JHipster - Uso base

Cosa è JHipster è un "generatore di applicazioni" che fornisce tutto lo stack necessario ad implementare una applicazione web e/o a microservizi basata su Spring Boot e AngularJs. E' dotato di un marketplace di componenti già pronte: https://www.jhipster.tech/#modules E' dotato di uno strumento web per la modellazione dello schema E-R: https://start.jhipster.tech/jdl-studio/ Prerequisiti - Java 8  - Node.js (usare la versione LTS 64-bit) - NPM viene installato con Node.js ma va aggiornato      $ npm install -g npm - Per usare il JHipster Marketplace, installare Yeoman:       $ npm install -g yo Uso base Gli step, presi dal sito ufficiale sono questi: 1. Installare JHipster:       $ npm install -g generator-jhipster Nota: per installare una versione specifica del generator:   $ npm install -g generator-jhipster@6.0.5 2. Crea una nuova directory ed entra dentro questa:   $ mkdir ...