MokaByte 60 - Febbraio 2002 
Spedire email con
le API JavaMail
di
Martino Pezzoli
Le API del package JavaMail di Sun offrono delle funzionalitą molto interessanti per la gestione di un client di posta elettronica internet, vediamo come fare a spedire una e-mail includendo degli allegati

Introduzione
L'implementazione delle API JavaMail di Sun ( http://java.sun.com/products/JavaMail ) rispetta tutti gli internet standards imposti dal RFC822 e MIME; il package mette a disposizione gli strumenti per poter gestire completamente un client di posta infatti nella cartella lib dell'installazione troviamo i jar files per utilizzare i servizi di posta SMTP, POP3, IMAP e mail con le API per la gestione della posta (connessione e dialogo con il server, spedizione, ricezione, etc…). L'articolo si occuperà di illustrare le classi per la spedizione di un messaggio di posta; per la stesura dell'articolo è risultata utile la news TECH TIPS Java Developer Connection del 23 Ottobre 2001 ( http://java.sun.com/jdc/JDCTechTips ).

 

I componenti essenziali per spedire una mail
La spedizione di una cartolina è un'operazione semplicissima, servono le classi:

Session
Message
Address
Transport

Se, invece, vogliamo aggiungere degli allegati dobbiamo utilizzare anche le classi:

Multipart
BodyPart
DataSource
DataHandler


Queste ultime classi fanno parte del package JAF (Java Application Framework) incluso nello zip di installazione Sun JavaMail. JAF permette di definire i vari tipi di MIME dei data source degli allegati.

 

Spiegazione delle classi utilizzate

Session
Stabilisce una sessione o connessione con il server di posta; per ottenere una sessione si deve passare come parametro l'oggetto Properties che verrà utilizzato per la connessione.
Ecco il frammento di codice:

// Get system properties
Properties props = System.getProperties();

// Setup mail server
props.put("mail.smtp.host", smtpHost);

// Get session
Session session = Session.getDefaultInstance(props, null);

Message
Questa classe è abstract, quindi deve essere utilizzata una sua sottoclasse appropriata per l'utilizzo, come MimeMessage che implementa il MIME style del messaggio e-mail.
Ecco il frammento di codice che istanzia un message object e riempie i campi essenziali del messaggio di posta:

// Define message
MimeMessage message = new MimeMessage(session);

message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("Hello this is a mail message");

Address
Nel frammento di codice riportato sopra si può notare l'istanza di InternetAddress che è una sottoclasse della classe abstract Address e che serve per definire il mittente/i e il destinatario/i del messaggio. E' possibile aggiungere più destinatari utilizzando i metodi


addFrom(Address[] addresses)

oppure

addRecipients(Message.RecipientType type, Address[] addresses)

specificando il recipient type; inoltre sono a disposizione i campi CC (carbon copy) e BCC (blind carbon copy).

Transport
E' la classe che permette la spedizione del messaggio utilizzando l'SMTP server specificato nelle properties della sessione.

Multipart
Questa è la prima classe da utilizzare per poter spedire, insieme alla cartolina, anche degli allegati. Il concetto di fondo è che l'allegato è una parte a se stante che viene unita al header (letteralmente testata) del messaggio.
Ecco il codice di esempio:

// Create the multi-part
Multipart multipart = new MimeMultipart();

BodyPart
Questa classe è abstract e quindi viene utilizzata una sua sottoclasse specifica la MimeBodyPart che permette di costruire la parte corpo del messaggio di posta cioè il testo desiderato.
Ecco l'esempio di codice:

// Create part one
BodyPart messageBodyPart = new MimeBodyPart();

// Fill the message
messageBodyPart.setText("Here's the file");

// Add the first part
multipart.addBodyPart(messageBodyPart);

DataSource
Questa classe serve per poter utilizzare come "attachment" un file, in pratica incapsula l'oggetto file e fornisce i "data typing services".

DataHandler
Questa serve per poter manipolare, quindi aggiungere all'oggetto Multipart gli attachment indipendentemente dal tipo di oggetto.

Infine, come penso avrete già capito, un messaggio di posta è composto da tre parti ben definite:

  1. l'header con il mittente, destinatario, oggetto, CC, BCC … .
  2. il testo vero e proprio del messaggio.
  3. un'eventuale allegato, nel caso vi siano più allegati si aggiungeranno al Multipart object.

Segue l'esempio completo del codice proposto:

/* esempio di codice */
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

public class SimpleMailAttach {

public static void main (String args[]) throws Exception {
    String smtpHost = args[0];
    String from = args[1];
    String to = args[2];
    String filename = args[3];

    // Get system properties
    Properties props = System.getProperties();

    // Setup mail server
    props.put("mail.smtp.host", smtpHost);

    // Get session
    Session session = Session.getDefaultInstance(props, null);

    // Define message
    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress(from));
    message.addRecipient(Message.RecipientType.TO,
                         new InternetAddress(to));
    message.setSubject("Hello this is a mail message");

    // Create the multi-part
    Multipart multipart = new MimeMultipart();

    // Create part one
    BodyPart messageBodyPart = new MimeBodyPart();

    // Fill the message
    messageBodyPart.setText("Here's the file");

    // Add the first part
    multipart.addBodyPart(messageBodyPart);

    // Part two is attachment
    messageBodyPart = new MimeBodyPart();
    DataSource source = new FileDataSource(filename);
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(filename);

    // Add the second part
    multipart.addBodyPart(messageBodyPart);

    // Put parts in message
    message.setContent(multipart);

    // Send message
    Transport.send(message);
  }
}


Conclusioni
Naturalmente il codice della classe proposta è puramente didattico e volutamente segue una stesura procedurale per meglio far capire la dinamica del processo. E' consigliabile suddividere il codice in più metodi, così da comporre in modo personalizzato il messaggio di posta con i componenti desiderati, aggiungendo magari il metodo main(args[]) in coda alla classe per poterla invocare da linea di comando… voi che ne pensate?


Bibliografia
[1] Sun - http://java.sun.com/products/javamail/index.html
[2] Sun - http://java.sun.com/beans/glasgow/jaf.html
[3] Sun - http://developer.java.sun.com/developer/JDCTechTips/2001/tt1023.html#tip2


Martino Pezzoli DU in Informatica all'Università degli Studi di Milano - Polo Didattico e di Ricerca di Crema nel 1999, lavora presso la Fassi Gru Idrauliche SpA di Bergamo come IT Solution Manager la sua principale attività è quella di sviluppo software.

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it