JavaMail-Schnellstart

In JavaMail finden Sie APIs und Anbieterimplementierungen, mit denen Sie voll funktionsfähige E-Mail-Client-Anwendungen entwickeln können. "E-Mail-Client-Anwendungen" ruft Gedanken zu Microsoft Outlook hervor. und ja, Sie könnten Ihren eigenen Outlook-Ersatz schreiben. Ein E-Mail-Client muss sich jedoch überhaupt nicht auf einem Client-Computer befinden. In der Tat kann es sich um ein Servlet oder eine EJB handeln, die auf einem Remote-Server ausgeführt wird und dem Endbenutzer über einen Webbrowser Zugriff auf E-Mails bietet. Denken Sie an Hotmail (ja, Sie können auch Ihre eigene Version von Hotmail schreiben). Oder Sie können eine Benutzeroberfläche ganz vermeiden. Wie wäre es mit einem Auto-Responder, der eingehende Nachrichten liest und Antworten sendet, die an den ursprünglichen Absender angepasst sind?

In meinem eigenen Haustierprojekt liest ein sprechender E-Mail-Client eingehende Nachrichten, dh spricht. Es basiert auf einer Verfeinerung einer Idee, die ich in "Talking Java!" Ich werde dir später mehr darüber erzählen.

Beginnen Sie zunächst mit der Installation und Konfiguration der JavaMail-Software.

Konfiguration

Wenn Sie Java 2 Platform, Enterprise Edition (J2EE) 1.3 verwenden, haben Sie Glück: Es enthält JavaMail, sodass kein zusätzliches Setup erforderlich ist. Wenn Sie jedoch Java 2 Platform, Standard Edition (J2SE) 1.1.7 und höher ausführen und E-Mail-Funktionen für Ihre Anwendungen benötigen, laden Sie Folgendes herunter und installieren Sie es:

  • JavaMail
  • JavaBeans Activation Framework

Zum Installieren entpacken Sie einfach die heruntergeladenen Dateien und fügen die enthaltenen JAR-Dateien Ihrem Klassenpfad hinzu. Als Beispiel ist hier mein Klassenpfad für dieses Projekt:

.; 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 \ activity.jar 

Die mailapi.jarDatei enthält die Kern-API-Klassen, während die Dateien pop3.jarund smtp.jardie Provider-Implementierungen für die jeweiligen Mail-Protokolle enthalten. (Wir werden die imap.jarDatei in diesem Artikel nicht verwenden .) Stellen Sie sich die Anbieterimplementierungen ähnlich wie JDBC-Treiber (Java Database Connectivity) vor, jedoch eher für Messagingsysteme als für Datenbanken. Die mail.jarDatei enthält jede der oben genannten JAR-Dateien, sodass Sie Ihren Klassenpfad nur auf die Dateien mail.jarund beschränken activation.jarkönnen.

Mit der activation.jarDatei können Sie MIME-Typen (Multipurpose Internet Mail Extensions) verarbeiten, auf die über binäre Datenströme zugegriffen werden kann. Suchen Sie später im Abschnitt Nicht nur Nur-Text nach der DataHandlerKlasse .

Der Rest dieses Artikels bietet keine umfassende API-Abdeckung. Vielmehr werden Sie lernen, indem Sie tun. Wenn Sie nach detaillierten API-Informationen suchen, schauen Sie sich die PDF-Dateien und Javadocs an, die in den jeweiligen Download-Bundles enthalten sind.

Sobald Sie die Software installiert haben, müssen Sie E-Mail-Kontodaten abrufen, um die folgenden Beispiele ausführen zu können. Sie benötigen den SMTP-Servernamen (Simple Mail Transfer Protocol) und den POP-Servernamen (Post Office Protocol) Ihres Internetdienstanbieters, den Anmeldenamen Ihres E-Mail-Kontos und Ihr Postfachkennwort. Abbildung 1 zeigt meine Details - nicht die tatsächlichen, wie Sie verstehen -, wie sie von Microsoft Outlook verwendet werden.

E-Mail über SMTP senden

Das erste Beispiel zeigt, wie eine einfache E-Mail-Nachricht über SMTP gesendet wird. Unten finden Sie die SimpleSenderKlasse, die die Details Ihrer Nachricht von der Befehlszeile übernimmt und eine separate Methode aufruft send(...), um sie zu senden:

Paket com.lotontech.mail; import javax.mail. *; import javax.mail.internet. *; import java.util. *; / ** * Eine einfache E-Mail-Absenderklasse. * / public class SimpleSender {/ ** * Hauptmethode zum Senden einer in der Befehlszeile angegebenen Nachricht. * / public static void main (String args []) {try {String smtpServer = args [0]; String to = args [1]; String from = args [2]; String subject = args [3]; String body = args [4]; send (smtpServer, to, from, subject, body); } catch (Exception ex) {System.out.println ("Verwendung: java com.lotontech.mail.SimpleSender" + "smtpServer toAddress fromAddress subjectText bodyText"); } System.exit (0); }}

Führen Sie SimpleSenderals Nächstes die folgenden Schritte aus. Ersetzen Sie ihn smtp.myISP.netdurch Ihren eigenen SMTP-Server, wie aus Ihren E-Mail-Einstellungen abgeleitet:

> java com.lotontech.mail.SimpleSender smtp.myISP.net [email protected] [email protected] "Hallo" "Nur um Hallo zu sagen." 

Und wenn es funktioniert, sehen Sie am Empfangsende so etwas wie in Abbildung 2.

Die send(...)Methode vervollständigt die SimpleSenderKlasse. Ich werde zuerst den Code zeigen und dann die Theorie detailliert beschreiben:

/ ** * "send" -Methode zum Senden der Nachricht. * / public static void send (String smtpServer, String to, String from, String subject, String body) {try {Properties props = System.getProperties (); // - Anhängen an die Standardsitzung, oder wir könnten eine neue starten - props.put ("mail.smtp.host", smtpServer); Sitzung session = Session.getDefaultInstance (Requisiten, null); // - Neue Nachricht erstellen - Nachricht msg = new MimeMessage (session); // - Setze die Felder FROM und TO - msg.setFrom (neue InternetAddress (from)); msg.setRecipients (Message.RecipientType.TO, InternetAddress.parse (to, false)); // - Wir könnten auch CC-Empfänger einschließen - // if (cc! = Null) // msg.setRecipients (Message.RecipientType.CC //, InternetAddress.parse (cc, false)); // - Betreff und Text festlegen - msg.setSubject (Betreff); msg.setText (body);// - Setze einige andere Header-Informationen - msg.setHeader ("X-Mailer", "LOTONtechEmail"); msg.setSentDate (neues Datum ()); // - Nachricht senden - Transport.send (msg); System.out.println ("Nachricht gesendet OK."); } catch (Ausnahme ex) {ex.printStackTrace (); }}}

Beachten Sie zunächst, dass Sie eine Mail-Sitzung ( java.mail.Session) erhalten, ohne die Sie nichts tun können. In diesem Fall rufen Sie Session.getDefaultInstance(...)an, um eine freigegebene Sitzung zu erhalten, die andere Desktopanwendungen möglicherweise wiederverwenden. Sie können über die Session.getInstance(...)Methode auch eine völlig neue Sitzung einrichten , die für Ihre Anwendung eindeutig ist. Letzteres könnte sich für E-Mail-Clients als wichtig erweisen, die nicht auf Benutzerbasis isoliert sind, z. B. ein webbasiertes E-Mail-System, das mit Servlets implementiert ist.

Zum Einrichten einer Sitzung müssen Sie bestimmte Eigenschaften festlegen. Sie benötigen die mail.smtp.hostEigenschaft mindestens, wenn Sie Nachrichten über SMTP senden. Weitere Eigenschaften finden Sie in der API-Dokumentation.

Sobald Sie eine Sitzung haben, erstellen Sie eine Nachricht. In diesem Beispiel sind Setzen Sie die Nachricht des von und zu E - Mail - Adressen, der Gegenstand, und der Körpers Text, alle ursprünglich von der Kommandozeile übernommen. Sie sind auch einige Header - Informationen, einschließlich der Datumseinstellung, und Sie können angeben , cc - Empfänger , wenn Sie wollen.

Schließlich senden Sie die Nachricht über die javax.mail.TransportKlasse. Wenn Sie sich fragen, woher es unsere Mail-Sitzung kennt, schauen Sie zurück auf den Konstruktor der Nachricht.

Nicht nur einfacher Text

Die setText(...)Convenience-Methode in der Klasse javax.mail.Message(von der javax.mail.PartSchnittstelle geerbt ) setzt den Nachrichteninhalt auf die angegebene Zeichenfolge und den MIME-Typ auf text/plain.

Sie sind jedoch nicht auf einfachen Text beschränkt: Sie können andere Inhaltstypen über die setDataHandler(...)Methode senden . In den meisten Fällen können Sie unter "anderen Inhaltstypen" Dateianhänge wie Word-Dokumente verstehen. Weitere interessante Informationen finden Sie in diesem Code zum Senden eines serialisierten Java-Objekts:

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

Sie finden die DataHandlerKlasse nicht in der javax.mail.*Paketstruktur, da sie zum JAF-Paket (JavaBeans Activation Framework) gehört javax.activation. Denken Sie daran, dass Sie die JAF-Distribution sowie JavaMail heruntergeladen haben. JAF bietet einen Mechanismus für den Umgang mit typisierten Dateninhalten, was für Internetinhalte MIME-Typen bedeutet.

Und wenn Sie wirklich den obigen Code zum Senden eines Java-Objekts per E-Mail ausprobieren, haben Sie Probleme, die ByteArrayDataSourceKlasse zu finden, da sie weder enthalten mail.jarnoch eingeschlossen activation.jarist. Versuchen Sie es im JavaMail-Demoverzeichnis!

Für die Dateianhänge, an denen Sie anfangs eher interessiert sind, erstellen Sie eine javax.activation.FileDataSourceInstanz im DataHandlerKonstruktor des. Natürlich werden Sie wahrscheinlich keine Datei alleine senden. Vielmehr handelt es sich wahrscheinlich um einen Anhang zu einer Textnachricht. Dazu müssen Sie das Konzept der mehrteiligen Nachrichten verstehen, daher werde ich dieses Konzept jetzt im Zusammenhang mit dem Empfang von E-Mails vorstellen.

Erhalten Sie eine E-Mail über POP3

Zuvor habe ich die von javax.mail.Partimplementierte Schnittstelle vorgestellt javax.mail.Message. Ich werde jetzt die Nachrichtenteile erläutern, die in diesem Beispiel wichtig sind. Schauen Sie sich zunächst Abbildung 3 an.

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.

Schließlich achten Sie im obigen Code darauf, den Ordner und den Nachrichtenspeicher zu schließen, wenn Sie fertig sind, sodass nur die printMessage(...)Methode zum Abschließen dieser Klasse übrig bleibt .

Drucken Sie die Nachrichten

In diesem Abschnitt wird die frühere javax.mail.PartSchnittstellendiskussion relevant.