MokaByte Numero 22 - Settembre 1998
 
Le JavaMail-API 
di
Marco Molinari
Il nuovo set di api introdotte con il JDK 1.2 permettono una facile gestione della posta elettronica. 
Vediamo come  

 



Le nuove API di Sun, dall’introduzione del jdk 1.2, si distinguono tra API principali e estensioni, che stanno rispettivamente nelle gerarchie java.* e javax.*. Le API principali sono quelle che fanno parte del jdk, e che un fornitore di jdk deve provvedere aimplementare. Le estensioni, al contrario, sono quelle API considerate non fondamentali, che non devono essere per forza implementate e che possono essere distribuite a parte (unica eccezione sono le API Swing, che dopo vari peregrinazioni sono recentemente finite anch’esse nello spazio javax, pur essendo, per Java 1.2, delle API  fondamentali). Di queste estensioni fanno parte tra le altre Java3D, l’API delle servlet e l’oggetto di questo articolo, JavaMail.



Introduzione
I sistemi di posta elettronica sono composti da un client, il programma che permette di raccogliere le email, di vederle, di scriverle e di spedirle, e un server, che si occupa di conservare le email fino a quando il client non le richiede e di spedire le email agli altri server. JavaMail definisce solamente la parte client del sistema, dando allo sviluppatore la possibilità di creare dei programmi come Eudora e di dare alle proprie applicazioni la capacità di gestire la posta elettronica. Il sistema è esclusivamente definito in modo astratto, ed è studiato per essere facile da usare, potente e flessibile. E’ compito degli implementatori fornire le classi concrete per permettere l’utilizzo effettivo delle API. Comunque oltre al framework astratto Sun fornisce una implementazione dei protocolli SMTP e IMAP4; quest’ultimo è un protocollo per ricevere la posta, più potente e flessibile del POP3, maggiormente utilizzato in Internet; Sun dichiara di rendersi conto che una implementazione del POP3 è fondamentale per la diffusione di JavaMail e in effetti in rete si trovano già un paio di implementazioni del POP3 di terze parti, una delle quali distribuita sotto la stessa licenza di Mozilla (simile a sua volta alla licenza di Linux).
Java Mail
JavaMail si basa molto sul JavaBeans Activation Framework (JAF) per  l’interazione con i messaggi. JAF serve a identificare e processare le informazioni MIME da una certa sorgente ed è composto da una serie di funzioni per determinare il tipo di un dato, per scoprire le operazioni possibili su di esso e per dare accesso a queste operazioni, permettendo di istanziare dei JavaBeans appositi. Il tutto è estremamente lineare, come mostra questo segmento di codice:
 
FileDataSource fds = new FileDataSource(filename); 
DataHandler dh = new DataHandler(fds); 
CommandInfo bi = dh.getCommand("view"); 
if (bi == null) { 
    System.out.println("no viewer found, exiting"); 
    System.exit(1); 

Component c = (Component)dh.getBean(bi);
A questo punto c conterrà l’eventuale bean per mostrare il file “filename”. JAF permette di registrare sul proprio sistema i beans per i vari tipi di dati, anche se di base vengono fornite solo le funzioni “view” e “edit” per i file di tipo text/plain e la funzioni “view” per le image/gif; anche in questo caso I beans veri e propri dovranno essere forniti  all’implementatore.
JavaMail si basa su JAF nel senso che invece che da un FileDataSource il DataHandler proverrebbe dal corpo di un messaggio.
Un ipotetico sistema di posta che utilizzi JavaMail avrebbe tre livelli: l’applicazione vera e propria, che utilizzerebbe il JAF, l’API astratta JavaMail e l’implementazione di JavaMail dedicata al particolare protocollo utilizzato.
Le funzioni principali di JavaMail permettono di ricevere, creare e spedire messaggi. E’ anche possibile gestire le mailbox, organizzandone il contenuto in folders e eseguendo ricerche in esse.
Una delle classi fondamentali di JavaMail è Message. Questa classe viene utilizzata sia per comporre che per leggere un messaggio. Possiede metodi per ricavare e settare i dati del messaggio: il mittente, il destinatario, il contenuto ecc. Scrivere un messaggio è questione di poche righe: dopo aver creato un oggetto Session, che si occupa delle opzioni di configurazione della connessione,
 
Message msg = new Message(session); 
msg.setFrom(new InternetAddress("mm@gpa.it")); 
msg.setRecipient(Message.RecipientType.TO, new InternetAddress("boss@infomedia.it")); 
msg.setSubject("Articolo JavaMail"); 
msg.setContent("Sono in ritardo. Mi perdoni.","text/plain");
La spedizione vera e propria del messaggio è curata dalla classe Transport. Spedire un file di altro tipo è molto simile, come lo è trattare i messaggi in più parti: JavaMail li supporta tramite la classe Multipart, contenitore di vari BodyPart. Ad esempio:
 
Multipart mp = (Multipart)message.getContent(); 
BodyPart bp; 
for (int i=0; i<mp.getCount(); i++) 
    bp = mp.getBodyPart(i);
Ottenute le BodyPart, su di esse si può agire come sui Message. Oltre che come un DataHandler adatto al JAF, il contenuto di un messaggio può essere ottenuto come InputStream o come oggetto Java, anche se quest’ultima opzione è in realtà implementata usando JAF. Un’altra funzione di Message è resa tramite l’oggetto Flags: i Message vengono tenuti in oggetti Folder, e Flags permette di avere informazioni sullo stato dei messaggi nel Folder: ad esempio se il messaggio è stato visto, se è segnato o se ha avuto una replica.  Un’altra classe fondamentale è Store, una classe astratta che definisce i metodi per connettersi al database che contiene il sistema di folders e di messaggi. Le implementazioni sono libere di gestire il database come preferiscono e di implementare il protocollo desiderato per ricevere i messaggi. Tipicamente la posta elettronica prevede tre tipi di funzionamento per questo tipo di meccanismo: online, offline e disconnesso. La modalità online lascia la posta sul server, richiedendola quando serve e manipolandola remotamente; è questo uno dei campi in cui il protocollo IMAP4 è superiore al POP3, che invece è utilizzabile quasi esclusivamente nella modalità “offline”, ovvero scaricando la posta e lavorandoci localmente. La modalità disconnessa invece mantiene due copie della posta, una locale e una remota, e le sincronizza a ogni connessione. Questa modalità, facente parte dall’IMAP4, non è ancora supportata da JavaMail, anche se nelle specifiche viene dichiarato che probabilmente verrà supportata in futuro e nelle FAQ si dice che un client può tranquillamente implementare la modalità disconnessa con le interfaccie presenti attualmente. Vediamo un semplice esempio per prendere i messaggi da una casella di posta, considerando come prima di avere un oggetto Session con i dati della connessione:
 
Store s = session.getStore(); 
Folder defaultFolder = s.getDefaultFolder(); 
Message[] messages = defaultFolder.getMessages();
Sempre attorno alla classe Store girano le funzioni di ricerca, tramite il metodo search che prende un criterio di ricerca anche complesso (composto di funzioni booleane) e restituisce un array di Message. Da notare invece che le operazioni di filtraggio sono solo promesse per una versione futura dell’ API, anche se potrebbero essere implementate facilmente dal client. La terza classe fondamentale su cui si basa JavaMail è Transport. Questa classe contiene i metodi per spedire effettivamente i messaggi, e le classi che la implementano definiscono i vari protocolli di spedizione, come ad esempio l’SMTP. Una caratteristica molto interessante di tutta JavaMail è l’uso degli eventi. Infatti molte classi generano eventi in stile JDK 1.1, permettendo a dei listener di registrarsi e di reagire di conseguenza. Ad esempio le sottoclassi di Transport generano TransportEvent quando viene chiamato il metodo sendMessage(): questo evento contiene informazioni sul successo della spedizione.
Una lacuna in JavaMail, che verrà corretta in una futura versione, è l’impossibilità di spedire messaggi crittati o firmati. Nelle specifiche una appendice descrive come questa potrebbe essere progettata.

Conclusione
JavaMail è un prodotto estremamente flessibile. Sun si augura che protocolli come NNTP, MAPI e Lotus Notes vengano presto implementati sulla base della loro API; questo probabilmente avverrà, considerando che alle specifiche hanno partecipato in parte anche persone di Novell, Lotus e IBM; un sistema di posta neutrale e universale è comodo anche ai fornitori di protocolli proprietari, che avrebbero una piattaforma di funzioni comuni e potrebbero poi estendere a piacere le capacità del proprio sistema.

Bibliografia


 
 
 
 
 
 

MokaByte Web  1998 - www.mokabyte.it 
MokaByte ricerca nuovi collaboratori. Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it