"Null" altro che un blog

at java.lang.NumberFormatException.forInputString(Unknown Source) at java.lang.Integer.parseInt(Unknown Source) at java.lang.Integer.parseInt(Unknown Source)

mercoledì 17 febbraio 2010

Da Java a XML e ritorno: un problema frequente

Il linguaggio XML, con l'affermarsi del web orientato ai servizi ed un uso sempre più massiccio del cosiddetto Web semantico, è diventato oramai uno standard imprescindibile all'interno della programmazione web, specialmente lato server.
Questa presenza sempre più costante nelle applicazioni web ha reso necessario uno sviluppo di appositi framework per la gestione dei file XML e le relative lettura e scrittura.
Risultano anzitutto necessari i cosiddetti parser XML, utilizzati esclusivamente nella fase di analisi (parserizzazione) del flusso di byte costituenti il file XML. Tra questi si distinguono due famiglie distinte, da un lato SAX(Simple API for XML), un'interfaccia che permette di interpretare dei file XML mediante una lettura basata su eventi, dall'altro la DOM(Document Object Model), che implementa le stesse funzionalità di SAX, ma lo fa costruendo un albero in cui ogni nodo rappresenta un elemento del file analizzato.
Per una applicazione web scritta in un linguaggio orientato ad oggetti, come ad esempio Java, una procedura molto utile risulta essere quella di mappare il contenuto del file XML in corrispondenti oggetti, in modo da manipolare i dati in maniera agile, come appunto dei veri e propri oggetti.
Per mappare la struttura dei documenti XML all'interno di apposite classi Java risulta molto comodo l'utilizzo del framework Castor, sviluppato del gruppo Exolab.
Questo framework è in grado di generare automaticamente, a partire da un XML Schema Definition, delle classi Java complete di costruttori e metodi per associare ad ogni elemento previsto dall'XSD un determinato valore.
Le classi generate, oltre alle property get/set, presentano caratteristiche molto interessanti. Ogni classe rappresenta un diverso tag descritto nell'XSD, e tale classe prevede un metodo marshall ed un metodo unmarshall che effettuano le operazioni di traduzione da XSD a codice Java e viceversa.
Il marshalling del documento, ovvero la traduzione del codice Java in linguaggio XML viene eseguito su un OutputStream, il quale corrisponderà al flusso mediante il quale si vuole trasportare il file XML generato.
Per quanto riguarda l'unmarshalling vengono generati metodi che permettono di popolare l'oggetto a partire da un InputStream, ovvero il flusso di dati in ingresso corrispondenti al file XML da mappare all'interno delle classi Java.
Ogni classe generata contiene inoltre un ulteriore metodo validate, che esegue un controllo su tutti gli attributi della classe in base ai vincoli definiti nello schema, ed un metodo booleano isValid che ritorna True se l'oggetto presenta una struttura corretta rispetto all'XSD.
Nel caso in cui un oggetto non è stato costruito correttamente, ad esempio un tag non è stato riempito, il metodo marshall lancerà una MarshallException e non costruirà l'elemento XML.

Mostriamo di seguito un esempio di codice Java generato dal framework Castor, tale esempio è relativo ai metodi isValid, validate e marshall della classe che mappa il tag , radice di un file XML descritto da un opportuno XSD.
 
public boolean isValid(){
try {
validate();
}
catch (org.exolab.castor.xml.ValidationException vex) {
return false;
}
return true;
}
public void marshal(java.io.Writer out) throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException{
Marshaller.marshal(this, out);
}

public void setPage(Page page)
{
this._page = page;
}
public void setPage(Page page) {
this._page = page;
}
public static Pages unmarshal(java.io.Reader reader) throws org.exolab.castor.xml.MarshalException,org.exolab.castor.xml.ValidationException
{
return (Pages) Unmarshaller.unmarshal(Pages.class, reader);
}

public void validate()throws org.exolab.castor.xml.ValidationException {
org.exolab.castor.xml.Validator validator = new
org.exolab.castor.xml.Validator();
validator.validate(this);
     }
 }

Nessun commento: