Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Comporre e inviare e-mail con Java

Sfruttare le API di JavaMail per creare e inviare, a uno o più indirizzi, messaggi di posta elettronica
Sfruttare le API di JavaMail per creare e inviare, a uno o più indirizzi, messaggi di posta elettronica
Link copiato negli appunti

È frequente ricevere messaggi automatici di posta elettronica, ad esempio per un acquisto on-line o per la registrazione ad un sito di nostro interesse, che ci informano sull'esito delle operazioni che abbiamo effettuato.

JavaMail è una serie di API (Application Programming Interface) che rendono semplice ed agevole la scrittura di codice Java per gestire proprio l'invio automatico di e-mail. JavaMail dipende, in realtà, da un'altra serie di API note come JAF: JavaBeans Activation Framework. Come vedremo tra breve sarà necessario importare entrambe queste librerie all'interno della nostra applicazione.

Come funziona la posta elettronica

Una rapida rinfrescata alla memoria su come funzioni la posta elettronica potrà essere utile soprattutto a chi non ha molto chiari alcuni concetti importanti.

Quando inviamo o riceviamo una e-mail utilizziamo, solitamente, un software specializzato come Microsoft Outlook o Eudora. Questo genere di applicazioni sono definite mail client e si prendono cura di comunicare con il mail server per inviare e ricevere i messaggi di posta elettronica.

In realtà, esistono due tipologie di mail server: il sending server ed il receiving server. Il primo si occupa di smistare i messaggi mentre il secondo è adibito alla ricezione degli stessi.

Figura 1. Flusso generato dall'invio di un'email
flusso invio email

Il processo di instradamento di una e-mail è basato sull'utilizzo di alcuni protocolli specifici. Vediamo quali sono:

  • SMTP Simple Mail Transfer Protocol
  • POP Post Office Protocol
  • IMAP Internet Message Access Protocol
  • MIME Multipurpose Internet Message Extensions

Come installare JavaMail

Probabilmente, se sulla propria macchina si sta utilizzando J2EE, le API di JavaMail e di JAF saranno già presenti sul sistema (sarà sufficiente verificarlo cercando i file "mail.jar" e "activation.jar" nelle cartelle di installazione dell'Application Server). In caso contrario, sarà necessario procedere nel seguente modo:

  • Scaricare il file javamail-1_4.zip
  • Scaricare il file jaf-1_1-fr.zip
  • Estrarre il contenuto dei due file .zip
  • Copiare i file mail.jar e activation.jar (rispettivamente localizzati nelle directory javamail-1.4 e jaf-1.1) all'interno della directory jre1.x.x_xx/lib/ext

Come creare ed inviare una e-mail

È arrivato il momento di vedere all'opera JavaMail. Scriveremo una semplice applicazione web che consenta all'utente di creare un messaggio di e-mail in formato testo ed inviarlo ad un destinatario a sua scelta. L'applicazione sarà così strutturata:

  • Una pagina html
  • Una classe helper
  • Una servlet

Vediamo il codice dei vari componenti:

Listato 1. index.html (vedi codice completo

...
<form action="MailServlet" method="post">

...<input type="text" name="mittente
...<input type="text" name="destinatario
...<input type="text" name="oggetto

...<textarea name="contenuto

...<input type="submit" value="Invia
</form>
...

Listato 2. MailUtility.java (vedi codice completo

...
  public static void sendMail (String dest, String mitt, String oggetto, String testoEmail)
      throws MessagingException
  {
    // Creazione di una mail session
    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.mioprovider.it");
    Session session = Session.getDefaultInstance(props);

    // Creazione del messaggio da inviare
    MimeMessage message = new MimeMessage(session);
    message.setSubject(oggetto);
    message.setText(testoEmail);

    // Aggiunta degli indirizzi del mittente e del destinatario
    InternetAddress fromAddress = new InternetAddress(mitt);
    InternetAddress toAddress = new InternetAddress(dest);
    message.setFrom(fromAddress);
    message.setRecipient(Message.RecipientType.TO, toAddress);

    // Invio del messaggio
    Transport.send(message);
  }
...

Listato 3. MailServlet.java (vedi codice completo

...
    String mitt = request.getParameter("mittente");
    String dest = request.getParameter("destinatario");
    String oggetto = request.getParameter("oggetto");
    String testo = request.getParameter("contenuto");

    response.setContentType("text/html");
    PrintWriter out = response.getWriter();

    try
    {
      MailUtility.sendMail(dest, mitt, oggetto, testo);
      out.println("Invio messaggio OK!");
    }
...

Analizziamo il codice. Come è facile notare, il compito della Servlet è quello di reperire i dati dalla request (che nel nostro caso sono: mittente, destinatario, oggetto e contenuto) e inoltrarli alla classe MailUtility attraverso il metodo sendMail().

La classe MailUtility si occuperà, come anticipato, della creazione ed invio del messaggio di posta elettronica vero e proprio. È possibile suddividere le operazioni svolte da questa classe in quattro passi:

Creazione di una sessione di tipo mail (mail session

Per questo scopo è necessario identificare l'indirizzo del server SMTP da utilizzare (nel codice dell'esempio abbiamo usato un indirizzo fittizio: smtp.mioprovider.it mail.from mail.user

Per creare l'oggetto sessione (di classe javax.mail.Session, da non confondere assolutamente con quello di classe HttpSession), viene definito un oggetto di tipo java.util.Properties, al quale vengono passate tutte le informazioni appena menzionate.

Attraverso il metodo statico getDefaultInstance(), infine, si procede alla creazione vera e propria della mail session, avendo cura di passare a tale metodo l'oggetto di classe Properties istanziato in precedenza. È importante sottolineare il fatto che il metodo getDefaultInstance() crea una nuova sessione soltanto se non ne è già attiva una.

Creazione del messaggio

Attraverso l'istruzione: new MimeMessage(session) si procede alla creazione di un nuovo messaggio e-mail. Subito dopo, si procede alla impostazione delle proprietà dell'oggetto stesso, utilizzando i metodi setSubject() e setText(). Il primo imposterà l'oggetto (inteso come subject) del nostro messaggio, mentre il secondo si occuperà di definire il contenuto (body) della e-mail.

Da notare che l'utilizzo del metodo setText() fa sì che il messaggio venga automaticamente impostato in modalità testo (plain text). Qualora si desiderasse, invece, creare un messaggio di tipo HTML, sarà sufficiente utilizzare il metodo alternativo setContent(), passando come parametro una stringa composta dagli opportuni tag HTML. Ad esempio:

message.setContent("<h2>Questo è il corpo del messaggio HTML</h2>", "text/html");

Creazione degli indirizzi

Il terzo passo è quello di aggiungere al messaggio, creato al punto precedente, gli indirizzi del destinatario e del mittente. Tale operazione, nel nostro esempio, è effettuata attraverso le seguenti righe di codice:

InternetAddress fromAddress = new InternetAddress(mitt);
InternetAddress toAddress = new InternetAddress(dest);
message.setFrom(fromAddress);
message.setRecipient(Message.RecipientType.TO, toAddress);

La classe javax.mail.internet.InternetAddress (derivata dalla classe Address) permette con estrema facilità di definire un indirizzo di posta elettronica. Tutto quello che serve è una stringa in input contenente l'indirizzo e-mail da creare. È anche possibile associare un indirizzo email ad un nome; in tal caso sarà necessario passare anche un secondo parametro al costruttore della classe, ad esempio:

InternetAddress fromAddress = new InternetAddress("myemail.mioprovider.it", "Marco Altese");

Un messaggio di posta elettronica deve poter consentire anche l'invio ad altri indirizzi per conoscenza (carbon copy, più noto con l'acronimo CC) e/o in copia nascosta (blind carbon copy, più noto con l'acronimo BCC). La classe da utilizzare per la creazione di tali indirizzi è la stessa (InternetAddress). Quello che varia è semplicemente il primo parametro passato al metodo setRecipient(). La classe Message.RecipientType consente tale differenziazione attraverso l'uso dei seguenti valori:

  • Message.RecipientType.TO
  • Message.RecipientType.CC
  • Message.RecipientType.BCC.

Infine, per inviare una email a più indirizzi contemporaneamente, bisognerà avvalersi del metodo setRecipients() della classe MimeMessage, passando, come secondo parametro, un array di elementi di tipo Address. Ad esempio:

Address mailAddresses = { new InternetAddress(firstaddress@provider.it),
new InternetAddress(secondaddress@provider.it),
new InternetAddress(thirdaddress@provider.it),
new InternetAddress(fourthaddress@provider.it) };
message.setRecipient(Message.RecipientType.TO, mailAddresses);

Invio del messaggio

Siamo arrivati al momento conclusivo: l'invio del nostro messaggio. A tale scopo utilizzeremo il metodo statico send() della classe javax.mail.Transport, passandogli come argomento l'oggetto di classe MimeMessage, creato al punto precedente. Se tutto è andato per il verso giusto la nostra semplice applicazione invierà un messaggio di posta elettronica verso il destinatario prescelto, visualizzando la seguente web form di risposta:

Figura 2. Risultato
risultato script

Attenzione a non testare l'applicazione con indirizzi a caso per evitare messaggi non graditi a persone non conosciute! Meglio provare con il nostro indirizzo personale.

Due parole, per concludere, sulle eccezioni che potrebbero scatenarsi durante l'invio di un messaggio. I metodi della classe MimeMessage che sono stati elencati, in caso di errore, sollevano un'eccezione di tipo javax.mail.MessagingException.

Una eccezione di tipo javax.mail.internet.AddressException, invece, viene sollevata dal costruttore della classe InternetAddress qualora venisse fornito un indirizzo non corretto. Tuttavia, poiché tale classe deriva dalla MessagingException, sarà sufficiente catturare tutte le eccezioni di questo tipo (a meno che non si voglia circoscrivere in modo più approfondito l'eventuale errore).

Anche l'eccezione javax.mail.SendFailedException deriva dalla MessagingException e viene scatenata in caso di errore durante l'invocazione del metodo send() della classe Transport.

Ti consigliamo anche