Avvio rapido di JavaMail

In JavaMail troverai API e implementazioni di provider che ti consentono di sviluppare applicazioni client di posta elettronica completamente funzionali. "Applicazioni client di posta elettronica" richiama pensieri di Microsoft Outlook; e, sì, potresti scrivere la tua sostituzione di Outlook. Ma un client di posta elettronica non deve affatto risiedere su una macchina client. In effetti, potrebbe essere un servlet o un EJB in esecuzione su un server remoto, che fornisce all'utente finale l'accesso alla posta elettronica tramite un browser Web. Pensa a Hotmail (sì, potresti scrivere anche la tua versione di Hotmail). Oppure potresti evitare del tutto un'interfaccia utente. Che ne dici di un risponditore automatico che legge i messaggi in arrivo e invia risposte, personalizzate in base al mittente originale?

Nel mio progetto per animali domestici, un client di posta elettronica parlante legge, cioè parla, i messaggi in arrivo. Si basa su un perfezionamento di un'idea che ho introdotto in "Talking Java!" Ti racconterò di più in seguito.

Per ora, inizia installando e configurando il software JavaMail.

Impostare

Se utilizzi Java 2 Platform, Enterprise Edition (J2EE) 1.3, sei fortunato: include JavaMail, quindi non è richiesta alcuna configurazione aggiuntiva. Se, tuttavia, stai utilizzando Java 2 Platform, Standard Edition (J2SE) 1.1.7 e versioni successive e desideri funzionalità di posta elettronica per le tue applicazioni, scarica e installa quanto segue:

  • JavaMail
  • JavaBeans Activation Framework

Per installare, decomprimere semplicemente i file scaricati e aggiungere i file jar contenuti al proprio classpath. Ad esempio, ecco il mio percorso di classe per questo progetto:

.; C: \ Apps \ Java \ javamail-1.2 \ mail.jar; C: \ Apps \ Java \ javamail-1.2 \ mailapi.jar; C: \ Apps \ Java \ javamail-1.2 \ pop3.jar; C: \ Apps \ Java \ javamail-1.2 \ smtp.jar; C: \ Apps \ Java \ jaf-1.0.1 \ activation.jar 

Il mailapi.jarfile contiene le classi API principali, mentre i file pop3.jare smtp.jarcontengono le implementazioni del provider per i rispettivi protocolli di posta. (Non useremo il imap.jarfile in questo articolo.) Pensa alle implementazioni del provider come simili ai driver JDBC (Java Database Connectivity), ma per i sistemi di messaggistica piuttosto che per i database. Per quanto riguarda il mail.jarfile, contiene ciascuno dei file jar sopra, quindi è possibile limitare il percorso di classe solo ai file mail.jare activation.jar.

Il activation.jarfile consente di gestire i tipi MIME (Multipurpose Internet Mail Extensions) accessibili tramite flussi di dati binari. Cerca più tardi la DataHandlerclasse nella sezione Non solo testo normale .

Per la cronaca, il resto di questo articolo non offre una copertura API completa; piuttosto, imparerai facendo. Se stai cercando informazioni API approfondite, guarda i file PDF e Javadoc inclusi nei rispettivi pacchetti di download.

Dopo aver installato il software, è necessario ottenere i dettagli dell'account di posta elettronica per eseguire gli esempi che seguono. Avrai bisogno del nome del server SMTP (Simple Mail Transfer Protocol) dell'ISP e del nome del server POP (Post Office Protocol), del nome di accesso dell'account e-mail e della password della casella di posta. La figura 1 mostra i miei dettagli - non quelli reali, capisci - come usati da Microsoft Outlook.

Invio di e-mail tramite SMTP

Il primo esempio mostra come inviare un messaggio di posta elettronica di base tramite SMTP. Di seguito troverai la SimpleSenderclasse, che prende i dettagli del tuo messaggio dalla riga di comando e chiama un metodo separato - send(...)- per inviarlo:

pacchetto com.lotontech.mail; importa javax.mail. *; importare javax.mail.internet. *; import java.util. *; / ** * Una semplice classe di mittente di posta elettronica. * / public class SimpleSender {/ ** * Metodo principale per inviare un messaggio fornito sulla riga di comando. * / public static void main (String args []) {try {String smtpServer = args [0]; Stringa a = args [1]; Stringa da = args [2]; Oggetto stringa = args [3]; Corpo della stringa = args [4]; invia (smtpServer, a, da, oggetto, corpo); } catch (eccezione ex) {System.out.println ("Utilizzo: java com.lotontech.mail.SimpleSender" + "smtpServer toAddress fromAddress subjectText bodyText"); } System.exit (0); }

Quindi, esegui SimpleSendercome di seguito. Sostituisci smtp.myISP.netcon il tuo server SMTP, come derivato dalle tue impostazioni di posta:

> java com.lotontech.mail.SimpleSender smtp.myISP.net [email protected] [email protected] "Hello" "Solo per dire Hello." 

E, se funziona, all'estremità ricevente vedrai qualcosa di simile a quello mostrato nella Figura 2.

Il send(...)metodo completa la SimpleSenderclasse. Mostrerò prima il codice, quindi descriverò la teoria:

/ ** * "invia" metodo per inviare il messaggio. * / public static void send (String smtpServer, String to, String from, String subject, String body) {try {Properties props = System.getProperties (); // - Collegamento alla sessione predefinita, oppure potremmo avviarne una nuova - props.put ("mail.smtp.host", smtpServer); Session session = Session.getDefaultInstance (props, null); // - Crea un nuovo messaggio - Message msg = new MimeMessage (session); // - Imposta i campi FROM e TO - msg.setFrom (new InternetAddress (from)); msg.setRecipients (Message.RecipientType.TO, InternetAddress.parse (to, false)); // - Potremmo includere anche destinatari CC - // if (cc! = Null) // msg.setRecipients (Message.RecipientType.CC //, InternetAddress.parse (cc, false)); // - Imposta l'oggetto e il corpo del testo - msg.setSubject (subject); msg.setText (corpo);// - Imposta altre informazioni sull'intestazione - msg.setHeader ("X-Mailer", "LOTONtechEmail"); msg.setSentDate (new Date ()); // - Invia il messaggio - Transport.send (msg); System.out.println ("Messaggio inviato OK."); } catch (eccezione ex) {ex.printStackTrace (); }}}

Innanzitutto, nota che stai ottenendo una sessione di posta ( java.mail.Session), senza la quale non puoi fare nulla. In questo caso stai chiamando Session.getDefaultInstance(...)per ottenere una sessione condivisa, che altre applicazioni desktop potrebbero riutilizzare; puoi anche impostare una sessione completamente nuova - tramite il Session.getInstance(...)metodo - che sarebbe unica per la tua applicazione. Quest'ultimo potrebbe rivelarsi importante per i client di posta elettronica non isolati per utente, come un sistema di posta elettronica basato sul Web implementato con servlet.

Per stabilire una sessione è necessario impostare determinate proprietà; come minimo, è necessaria la mail.smtp.hostproprietà se si inviano messaggi tramite SMTP. Troverai altre proprietà descritte nella documentazione API.

Una volta che hai una sessione, crea un messaggio. In questo esempio, stai impostando gli indirizzi di posta elettronica da e verso il messaggio, l' oggetto e il corpo del testo, tutti presi originariamente dalla riga di comando. Stai anche impostando alcune informazioni di intestazione, inclusa la data, e puoi specificare i destinatari cc se lo desideri.

Infine, invii il messaggio tramite la javax.mail.Transportclasse. Se ti chiedi come fa a sapere della nostra sessione di posta, guarda indietro al costruttore del messaggio.

Non solo testo semplice

Il setText(...)metodo di convenienza della classe javax.mail.Message(ereditato javax.mail.Partdall'interfaccia) imposta il contenuto del messaggio sulla stringa fornita e imposta il tipo MIME su text/plain.

Tuttavia, non sei limitato al testo normale: puoi inviare altri tipi di contenuto tramite il setDataHandler(...)metodo. Nella maggior parte dei casi puoi prendere "altri tipi di contenuto" per indicare file allegati, come documenti di Word, ma per qualcosa di un po 'più interessante, controlla questo codice per inviare un oggetto serializzato Java:

ByteArrayOutputStream byteStream = nuovo ByteArrayOutputStream (); ObjectOutputStream objectStream = nuovo ObjectOutputStream (byteStream); objectStream.writeObject (theObject); msg.setDataHandler (new DataHandler (new ByteArrayDataSource (byteStream.toByteArray (), "lotontech / javaobject")));

Non troverai la DataHandlerclasse all'interno della javax.mail.*struttura del pacchetto perché appartiene al pacchetto JavaBeans Activation Framework (JAF) javax.activation. Ricorda, hai scaricato la distribuzione JAF e JavaMail. JAF fornisce un meccanismo per la gestione del contenuto di dati tipizzati , che per contenuto Internet significa tipi MIME.

E se provi davvero il codice sopra per inviare un oggetto Java via e-mail, avrai problemi a localizzare la ByteArrayDataSourceclasse, in quanto né mail.jarné la activation.jarincludi. Prova a cercare nella directory demo di JavaMail!

Per quanto riguarda gli allegati di file a cui è più probabile che ti interessino inizialmente, creeresti javax.activation.FileDataSourceun'istanza nel DataHandlercostruttore di. Ovviamente, non è probabile che invii un file da solo; piuttosto, sarà probabilmente un allegato a un messaggio di testo. Per questo è necessario comprendere il concetto di messaggi in più parti, quindi introdurrò quel concetto ora, nel contesto della ricezione di posta elettronica.

Ricevi email tramite POP3

In precedenza, ho introdotto l' javax.mail.Partinterfaccia implementata da javax.mail.Message. Spiegherò ora le parti del messaggio, che sono importanti in questo esempio. Per iniziare, dai un'occhiata alla Figura 3.

Figure 3 shows a Message as created in the previous example that is both a message and message part, because it implements the Part interface. For any part, you can get its content (any Java object), and, in the case of a simple text message, the content object may be a String. For a multipart message, the content will be of type Multipart, from which we can get hold of the individual body parts, which themselves implement the Part interface.

In practice, all will become apparent as you step through the code for a SimpleReceiver class, which I'll present in three sections: first, the class definition and the main(...) method that takes connection details from the command line; second, the receive(...) method that captures and steps through the incoming messages; and finally, the printMessage(...) method that prints the header information and content of each message.

Here's the first section:

package com.lotontech.mail; import javax.mail.*; import javax.mail.internet.*; import java.util.*; import java.io.*; /** * A simple email receiver class. */ public class SimpleReceiver { /** * Main method to receive messages from the mail server specified * as command line arguments. */ public static void main(String args[]) { try { String popServer=args[0]; String popUser=args[1]; String popPassword=args[2]; receive(popServer, popUser, popPassword); } catch (Exception ex) { System.out.println("Usage: java com.lotontech.mail.SimpleReceiver" +" popServer popUser popPassword"); } System.exit(0); } 

I'll take you through a proper test drive later, but for now here is the command line to run it (remember to replace the command arguments with your mail settings):

> java com.lotontech.mail.SimpleReceiver pop.myIsp.net myUserName myPassword 

The receive(...) method -- called from main(...) -- opens your POP3 INBOX and steps through the messages in turn, each time calling printMessage(...). Here is the code:

 /** * "receive" method to fetch messages and process them. */ public static void receive(String popServer, String popUser , String popPassword) { Store store=null; Folder folder=null; try { // -- Get hold of the default session -- Properties props = System.getProperties(); Session session = Session.getDefaultInstance(props, null); // -- Get hold of a POP3 message store, and connect to it -- store = session.getStore("pop3"); store.connect(popServer, popUser, popPassword); // -- Try to get hold of the default folder -- folder = store.getDefaultFolder(); if (folder == null) throw new Exception("No default folder"); // -- ...and its INBOX -- folder = folder.getFolder("INBOX"); if (folder == null) throw new Exception("No POP3 INBOX"); // -- Open the folder for read only -- folder.open(Folder.READ_ONLY); // -- Get the message wrappers and process them -- Message[] msgs = folder.getMessages(); for (int msgNum = 0; msgNum < msgs.length; msgNum++) { printMessage(msgs[msgNum]); } } catch (Exception ex) { ex.printStackTrace(); } finally { // -- Close down nicely -- try { if (folder!=null) folder.close(false); if (store!=null) store.close(); } catch (Exception ex2) {ex2.printStackTrace();} } } 

Notice that you're obtaining a POP3 message-store wrapper from the session, then connecting to it using the mail settings originally supplied on the command line.

Once connected, you get a handle on the default folder -- effectively the root of the folder tree -- and, from there, the INBOX folder that holds the inbound messages. You open the INBOX for read-only access; you get hold of the messages and step through them one by one.

As an aside, you might wonder if you would ever want to open the INBOX for write access. You would if you intended to mark the messages as received and/or remove them from the server. In our example, you're only looking at them.

Infine, nel codice sopra ti stai occupando di chiudere la cartella e l'archivio dei messaggi al termine, che lascia solo il printMessage(...)metodo per completare questa classe.

Stampa i messaggi

In questa sezione, la javax.mail.Partdiscussione sull'interfaccia precedente diventa rilevante.