Démarrage rapide de JavaMail

Dans JavaMail, vous trouverez des API et des implémentations de fournisseur vous permettant de développer des applications client de messagerie entièrement fonctionnelles. "Applications client de messagerie" évoque des pensées de Microsoft Outlook; et, oui, vous pouvez écrire votre propre remplacement Outlook. Mais un client de messagerie n'a pas du tout besoin de résider sur une machine cliente. En effet, il peut s'agir d'un servlet ou d'un EJB s'exécutant sur un serveur distant, permettant à l'utilisateur final d'accéder au courrier électronique via un navigateur Web. Pensez à Hotmail (oui, vous pouvez également écrire votre propre version de Hotmail). Ou vous pouvez éviter complètement une interface utilisateur. Que diriez-vous d'un répondeur automatique qui lit les messages entrants et envoie des réponses, personnalisées en fonction de l'expéditeur d'origine?

Dans mon propre projet, un client de messagerie parlant lit - c'est-à-dire parle - les messages entrants. Il est basé sur le raffinement d'une idée que j'ai introduite dans "Talking Java!" Je vous en dirai plus plus tard.

Pour l'instant, commencez par installer et configurer le logiciel JavaMail.

Installer

Si vous utilisez Java 2 Platform, Enterprise Edition (J2EE) 1.3, vous avez de la chance: il inclut JavaMail, donc aucune configuration supplémentaire n'est requise. Cependant, si vous exécutez Java 2 Platform, Standard Edition (J2SE) 1.1.7 et versions ultérieures, et que vous souhaitez une fonctionnalité de messagerie électronique pour vos applications, téléchargez et installez les éléments suivants:

  • JavaMail
  • Framework d'activation JavaBeans

Pour installer, décompressez simplement les fichiers téléchargés et ajoutez les fichiers jar contenus à votre chemin de classe. À titre d'exemple, voici mon chemin de classe pour ce projet:

.; 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 

Le mailapi.jarfichier contient les classes API principales, tandis que les fichiers pop3.jaret smtp.jarcontiennent les implémentations de fournisseur pour les protocoles de messagerie respectifs. (Nous n'utiliserons pas le imap.jarfichier dans cet article.) Considérez les implémentations du fournisseur comme similaires aux pilotes JDBC (Java Database Connectivity), mais pour les systèmes de messagerie plutôt que pour les bases de données. Quant au mail.jarfichier, il contient chacun des fichiers jar ci-dessus, vous pouvez donc restreindre votre chemin de classe aux seuls fichiers mail.jaret activation.jar.

Le activation.jarfichier vous permet de gérer les types MIME (Multipurpose Internet Mail Extensions) accessibles via des flux de données binaires. Recherchez le DataHandlercours dans la section Not Just Plain Text plus tard.

Pour mémoire, le reste de cet article n'offre pas de couverture API complète; vous apprendrez plutôt en faisant. Si vous recherchez des informations détaillées sur l'API, consultez les fichiers PDF et Javadocs inclus dans les lots de téléchargement respectifs.

Une fois que vous avez installé le logiciel, vous devez obtenir les détails du compte de messagerie pour exécuter les exemples suivants. Vous aurez besoin du nom de serveur SMTP (Simple Mail Transfer Protocol) de votre FAI et du nom de serveur POP (Post Office Protocol), de votre nom de connexion à votre compte de messagerie et de votre mot de passe de boîte aux lettres. La figure 1 montre mes détails - pas les vrais, vous comprenez - tels qu'utilisés par Microsoft Outlook.

Envoi d'e-mails via SMTP

Le premier exemple montre comment envoyer un message électronique de base via SMTP. Ci-dessous, vous trouverez la SimpleSenderclasse, qui prend les détails de votre message de la ligne de commande et appelle une méthode distincte - send(...)- pour l'envoyer:

package com.lotontech.mail; import javax.mail. *; import javax.mail.internet. *; import java.util. *; / ** * Une classe d'expéditeur de courrier électronique simple. * / public class SimpleSender {/ ** * Méthode principale pour envoyer un message donné sur la ligne de commande. * / public static void main (String args []) {try {String smtpServer = args [0]; Chaîne à = args [1]; Chaîne de = args [2]; Sujet de la chaîne = args [3]; Corps de la chaîne = args [4]; envoyer (smtpServer, vers, depuis, sujet, corps); } catch (Exception ex) {System.out.println ("Utilisation: java com.lotontech.mail.SimpleSender" + "smtpServer toAddress fromAddress subjectText bodyText"); } System.exit (0); }

Ensuite, exécutez SimpleSendercomme ci-dessous. Remplacez-le smtp.myISP.netpar votre propre serveur SMTP, d'après vos paramètres de messagerie:

> java com.lotontech.mail.SimpleSender smtp.myISP.net [email protected] [email protected] "Bonjour" "Juste pour dire bonjour." 

Et, si cela fonctionne, à la réception, vous verrez quelque chose comme ce qui est montré dans la figure 2.

La send(...)méthode complète la SimpleSenderclasse. Je vais d'abord montrer le code, puis détailler la théorie:

/ ** * Méthode "envoyer" pour envoyer le message. * / public static void send (String smtpServer, String to, String from, String subject, String body) {try {Properties props = System.getProperties (); // - Attachement à la session par défaut, ou nous pourrions en démarrer une nouvelle - props.put ("mail.smtp.host", smtpServer); Session session = Session.getDefaultInstance (props, null); // - Créer un nouveau message - Message msg = new MimeMessage (session); // - Définit les champs FROM et TO - msg.setFrom (new InternetAddress (from)); msg.setRecipients (Message.RecipientType.TO, InternetAddress.parse (to, false)); // - Nous pourrions également inclure des destinataires CC - // if (cc! = Null) // msg.setRecipients (Message.RecipientType.CC //, InternetAddress.parse (cc, false)); // - Définit le sujet et le corps du texte - msg.setSubject (subject); msg.setText (corps);// - Définit d'autres informations d'en-tête - msg.setHeader ("X-Mailer", "LOTONtechEmail"); msg.setSentDate (nouvelle date ()); // - Envoie le message - Transport.send (msg); System.out.println ("Message envoyé OK."); } catch (Exception ex) {ex.printStackTrace (); }}}

Tout d'abord, notez que vous obtenez une session de messagerie ( java.mail.Session), sans laquelle vous ne pouvez rien faire. Dans ce cas, vous appelez Session.getDefaultInstance(...)pour obtenir une session partagée, que d'autres applications de bureau peuvent réutiliser; vous pouvez également configurer une toute nouvelle session - via la Session.getInstance(...)méthode - qui serait unique à votre application. Ce dernier pourrait s'avérer important pour les clients de messagerie non isolés sur une base par utilisateur, comme un système de messagerie Web implémenté avec des servlets.

L'établissement d'une session nécessite que vous définissiez certaines propriétés; au minimum, vous avez besoin de la mail.smtp.hostpropriété si vous envoyez des messages via SMTP. Vous trouverez d'autres propriétés décrites dans la documentation de l'API.

Une fois que vous avez une session, créez un message. Dans cet exemple, vous définissez les adresses e-mail de et de destination du message, l' objet et le corps du texte, tous extraits de la ligne de commande. Vous définissez également certaines informations d'en-tête, y compris la date, et vous pouvez spécifier des destinataires cc si vous le souhaitez.

Enfin, vous envoyez le message via la javax.mail.Transportclasse. Si vous vous demandez comment il connaît notre session de messagerie, revenez sur le constructeur du message.

Pas seulement du texte brut

La setText(...)méthode pratique de la classe javax.mail.Message(héritée de l' javax.mail.Partinterface) définit le contenu du message sur la chaîne fournie et définit le type MIME sur text/plain.

Cependant, vous n'êtes pas limité au texte brut: vous pouvez envoyer d'autres types de contenu via la setDataHandler(...)méthode. Dans la plupart des cas, vous pouvez prendre «autres types de contenu» pour désigner des pièces jointes, telles que des documents Word, mais pour quelque chose d'un peu plus intéressant, consultez ce code pour envoyer un objet sérialisé Java:

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

Vous ne trouverez pas la DataHandlerclasse dans la javax.mail.*structure du package car elle appartient au package JavaBeans Activation Framework (JAF) javax.activation. N'oubliez pas que vous avez téléchargé la distribution JAF ainsi que JavaMail. JAF fournit un mécanisme pour gérer le contenu de données typé , qui pour le contenu Internet signifie les types MIME.

Et si vous essayez vraiment le code ci-dessus pour envoyer un objet Java par courrier électronique, vous aurez du mal à localiser la ByteArrayDataSourceclasse, car ni mail.jarni l' activation.jarinclure. Essayez de chercher dans le répertoire de démonstration JavaMail!

En ce qui concerne les pièces jointes qui vous intéressent le plus au départ, vous créerez une javax.activation.FileDataSourceinstance dans le DataHandlerconstructeur de. Bien sûr, il est peu probable que vous envoyiez un fichier seul; il s'agira plutôt d'une pièce jointe à un message texte. Pour cela, vous devez comprendre le concept de messages en plusieurs parties, je vais donc vous présenter ce concept maintenant, dans le contexte de la réception d'e-mails.

Recevoir des e-mails via POP3

Plus tôt, j'ai présenté l' javax.mail.Partinterface implémentée par javax.mail.Message. Je vais maintenant expliquer ses parties de message, qui sont importantes dans cet exemple. Pour commencer, jetez un œil à la figure 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.

Enfin, dans le code ci-dessus, vous prenez soin de fermer le dossier et la banque de messages lorsque vous avez terminé, ce qui ne laisse que la printMessage(...)méthode pour compléter cette classe.

Imprimer les messages

Dans cette section, la javax.mail.Partdiscussion précédente sur l' interface devient pertinente.