Einfacher E-Mail-Versand mit SMTP in Java

+ andere TechDocs
+ Netzwerkfunktionen
+




Inhalt

  1. Vollständige Java-E-Mail-Implementierung
  2. E-Mail-Versand aus dem Kommandozeilenfenster
  3. E-Mail-Versand von Applet aus
  4. E-Mail-Versand per JSP Apache Jakarta Taglibs
  5. Programmierbeispiel: Einfachster E-Mail-Versand
  6. Programmierbeispiel mit Apache Commons Email
  7. Beispiele für Account-Einstellungen zu E-Mail-Providern


Vollständige Java-E-Mail-Implementierung

Vollständige Java-E-Mail-Implementierungen bieten zum Beispiel JavaMail und Apache Commons Email:



E-Mail-Versand aus dem Kommandozeilenfenster

Beispiele für im Kommandozeilenfenster ausführbare Programme zum Versand von E-Mails:



E-Mail-Versand von Applet aus

Unsignierte Applets können nicht ohne weiteres fremde Server ansprechen. Deshalb:



E-Mail-Versand per JSP Apache Jakarta Taglibs

Ein einfaches Programmierbeispiel zum E-Mail-Versand per JSP Apache Jakarta Taglibs finden Sie unter:



Programmierbeispiel: Einfachster E-Mail-Versand

SmtpSimple demonstriert einfachsten E-Mail-Versand zur Verdeutlichung der Funktionsweise. Für ernsthafte Anwendungen sollte besser JavaMail oder Apache Commons Email verwendet werden. Zu Letzterem gibt es anschließend ein Programmierbeispiel.

SmtpSimple funktionierte früher z.B. mit GMX (mail.gmx.net), Strato (post.strato.de) und T-Online (mailto.btx.dtag.de). Eventuell mussten Autorisierungsprozeduren vorgeschaltet werden (z.B. funktionierte T-Online-E-Mail nur mit T-Online-Internet-Zugang sowie GMX und Strato nur nach vorherigem POP3-Lesezugriff). Allerdings verschärfen die Provider mittlerweile die Autorisierungsprozeduren, so dass die Möglichkeiten individuell überprüft werden müssen.

Es kann entweder die Funktion SmtpSimple.sendEmail() in Java-Programme eingebunden werden, oder SmtpSimple als eigenständiges Kommandozeilenprogramm per java SmtpSimple eingesetzt werden.
Die Funktion SmtpSimple.sendEmail() macht keine Ausgaben (etwa per System.out.println()) und kann sowohl in Applets als auch in Applikationen verwendet werden. Der SMTP-Dialog wird returniert und kann angezeigt werden, was aber normalerweise nicht sinnvoll ist. Fehler werden durch Exceptions angezeigt.
Das Kommandozeilenprogramm (java SmtpSimple) listet beim Aufruf ohne Kommandozeilenparameter die notwendigen Parameter und ein Aufrufbeispiel auf. Beim Aufruf mit Parametern wird der SMTP-Dialog angezeigt. Im Fehlerfall endet das Programm mit gesetztem Errorlevel.

import java.net.*;
import java.io.*;

public class SmtpSimple
{
  private DataOutputStream os  = null;
  private BufferedReader   is  = null;
  private String           sRt = "";

  public static void main( String[] args )
  {
    System.out.println(
      "\nSmtpSimple.java. Send simple email.\nUsage:\n" +
      "  java SmtpSimple SmtpServer FromAdr FromRealName ToAdr ToRealName Subject Text\n" +
      "Example:\n" +
      "  java SmtpSimple mail.gmx.net MeinName@MeinProvider.de \"Torsten Horn\" x@y.z xyz S T\n" );
    if( null == args || 6 > args.length ) {
      System.out.println( "Error: parameters missing!" );
      System.exit( 1 );
    }
    try {
      SmtpSimple smtp = new SmtpSimple();
      System.out.println( smtp.sendEmail( args[0], args[1], args[2], args[3], args[4], args[5],
                                          ( 6 < args.length ) ? args[6] : null ) );
    } catch( Exception ex ) {
      System.out.println( "Error:\n" + ex );
      System.exit( 2 );
    }
    System.exit( 0 );
  }

  public synchronized final String sendEmail( String sSmtpServer,
                                              String sFromAdr, String sFromRealName,
                                              String sToAdr,   String sToRealName,
                                              String sSubject, String sText )
  throws IOException, Exception
  {
    Socket so = null;
    try {
      sRt = "";
      if( null == sSmtpServer  || 0 >= sSmtpServer.length() ||
          null == sFromAdr     || 0 >= sFromAdr.length()    ||
          null == sToAdr       || 0 >= sToAdr.length()      ||
          (  (null == sSubject || 0 >= sSubject.length())
          && (null == sText    || 0 >= sText.length())  )   )
        throw new Exception( "Invalid Parameters for SmtpSimple.sendEmail()." );
      if( null == sFromRealName || 0 >= sFromRealName.length() )  sFromRealName = sFromAdr;
      if( null == sToRealName   || 0 >= sToRealName.length() )    sToRealName   = sToAdr;
      so = new Socket( sSmtpServer, 25 );
      os = new DataOutputStream( so.getOutputStream() );
      is = new BufferedReader(
           new InputStreamReader( so.getInputStream() ) );
      so.setSoTimeout( 10000 );
      writeRead( true, "220", null );
      writeRead( true, "250", "HELO " + sSmtpServer + "\n" );
      writeRead( true, "250", "RSET\n" );
      writeRead( true, "250", "MAIL FROM:<" + sFromAdr + ">\n" );
      writeRead( true, "250", "RCPT TO:<" + sToAdr + ">\n" );
      writeRead( true, "354", "DATA\n" );
      writeRead( false, null, "To: " + sToRealName + " <" + sToAdr + ">\n" );
      writeRead( false, null, "From: " + sFromRealName + " <" + sFromAdr + ">\n" );
      writeRead( false, null, "Subject: " + sSubject + "\n" );
      writeRead( false, null, "Mime-Version: 1.0\n" );
      writeRead( false, null, "Content-Type: text/plain; charset=\"iso-8859-1\"\n" );
      writeRead( false, null, "Content-Transfer-Encoding: quoted-printable\n\n" );
      writeRead( false, null, sText + "\n" );
      writeRead( true, "250", ".\n" );
      writeRead( true, "221", "QUIT\n" );
      return sRt;
    } finally {
      if( is != null ) try { is.close(); } catch (Exception ex) {}
      if( os != null ) try { os.close(); } catch (Exception ex) {}
      if( so != null ) try { so.close(); } catch (Exception ex) {}
    }
  }

  private final void writeRead( boolean bReadAnswer,
                                String  sAnswerMustStartWith,
                                String  sWrite )
  throws IOException, Exception
  {
    if( null != sWrite && 0 < sWrite.length() ) {
      sRt += sWrite;
      os.writeBytes( sWrite );
    }
    if( bReadAnswer ) {
      String sRd = is.readLine() + "\n";
      sRt += sRd;
      if( null != sAnswerMustStartWith
          && 0 < sAnswerMustStartWith.length()
          && !sRd.startsWith( sAnswerMustStartWith ) )
        throw new Exception( sRt );
    }
  }
}


Programmierbeispiel mit Apache Commons Email

package mail;

import java.io.*;
import java.util.*;
import org.apache.commons.mail.*;

/** E-Mail mit Anhang versenden */
public class MailApp
{
   private static Map<String,String> mimeContentTypesMap = null;

   /** Nur zum Testen */
   public static void main( String[] args ) throws IOException, EmailException
   {
      String mailserver      = "..."; // SMTP-Mailserver-Host-Adresse
      String username        = "..."; // Mailserver-Benutzername
      String password        = "..."; // Mailserver-Passwort
      String absender        = "..."; // Absender-Email-Adresse
      String empfaenger      = "..."; // Empfaenger-Email-Adresse
      String betreff         = "Test: Mein Betreff mit den Sonderzeichen äöüß\u20AC"; // '\u20AC' = Euro
      String text            = "Mein E-Mail-Text mit den Sonderzeichen äöüß\u20AC";   // '\u20AC' = Euro
      String textCharset     = "UTF-8";
      String anhangDateiName = ( args != null && args.length > 0 ) ? args[0] : "Test.pdf"; // Anhangdatei

      System.out.println( sendeEmailMitAnhang( mailserver, username, password, absender, empfaenger,
                                               textCharset, betreff, text, anhangDateiName ) );
   }

   /** E-Mail mit Datei als Anhang versenden */
   public static String sendeEmailMitAnhang(
         String mailserver, String username, String password, String absender, String empfaenger,
         String textCharset, String betreff, String text, String anhangDateiName ) throws IOException, EmailException
   {
      String      anhangContentType = getMimeContentTypeInclCharset( anhangDateiName );
      InputStream anhangInputStream = new FileInputStream( anhangDateiName );
      try {
         return sendeEmailMitAnhang( mailserver, username, password, absender, empfaenger, textCharset, betreff, text,
                                     anhangContentType, anhangInputStream, anhangDateiName, anhangDateiName );
      } finally {
         anhangInputStream.close();
      }
   }

   /** E-Mail mit Anhang aus Stream mit Apache Commons Email versenden
       (http://commons.apache.org/proper/commons-email/apidocs/index.html) */
   public static String sendeEmailMitAnhang(
         String mailserver, String username, String password, String absender, String empfaenger,
         String textCharset, String betreff, String text,
         String anhangContentType, InputStream anhangInputStream, String anhangDateiName, String anhangBeschreibung )
         throws IOException, EmailException
   {
      MultiPartEmail email = new MultiPartEmail();
      if( username != null && password != null ) {
         email.setAuthenticator( new DefaultAuthenticator( username, password ) );
         email.setSSLOnConnect( true );
      }
      email.setHostName( mailserver  );
      email.setFrom(     absender    );
      email.addTo(       empfaenger  );
      email.setCharset(  textCharset );
      email.setSubject(  betreff     );
      email.setMsg(      text        );
      email.attach( new ByteArrayDataSource( anhangInputStream, anhangContentType ),
                    anhangDateiName, anhangBeschreibung, EmailAttachment.ATTACHMENT );
      return email.send();
   }

   /** Ermittlung einiger MIME-Content-Typen aus der Dateiendung.
       Achtung: Dies sind nur Beispiele die eventuell ergaenzt oder modifiziert werden muessen.
       Weitere MIME-Typen siehe: http://de.selfhtml.org/diverses/mimetypen.htm.
       Achtung: Eventuell muessen die MIME-Content-Type-Strings um das Character-Encoding ergaenzt werden,
       z.B. "text/plain; charset=ISO-8859-1" oder "text/xml; charset=UTF-8",
       bzw. die bereits eingetragenen Character-Encodings durch andere ersetzt werden (z.B. bei text/html). */
   public static String getMimeContentTypeInclCharset( String filename )
   {
      final String[] mimeContentTypesArr = {
            "txt", "text/plain; charset=ISO-8859-1", "csv", "text/csv; charset=ISO-8859-1", "pdf", "application/pdf",
            "zip", "application/zip", "htm", "text/html; charset=ISO-8859-1", "html", "text/html; charset=UTF-8",
            "xml", "text/xml; charset=UTF-8", "xls", "application/vnd.ms-excel", "bin", "application/octet-stream" };
      if( filename != null && filename.trim().length() > 0 && filename.indexOf( '.' ) >= 0 ) {
         String fnExt = filename.substring( filename.lastIndexOf( '.' ) ).trim().toLowerCase( Locale.GERMAN );
         if( fnExt.length() > 1 ) {
            fnExt = fnExt.substring( 1 );
            if( mimeContentTypesMap == null ) {
               Map<String,String> mimeContentTypesMapTemp = new HashMap<String,String>();
               for( int i = 0; i < mimeContentTypesArr.length; i += 2 ) {
                  mimeContentTypesMapTemp.put( mimeContentTypesArr[i], mimeContentTypesArr[i+1] );
               }
               mimeContentTypesMap = mimeContentTypesMapTemp;
            }
            String mimeContentType = mimeContentTypesMap.get( fnExt );
            if( mimeContentType != null ) {
               return mimeContentType;
            }
         }
      }
      return "application/octet-stream";
   }
}

Maven-Dependencies:

  <dependencies>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-email</artifactId>
      <version>1.3.1</version>
    </dependency>
  </dependencies>

Empfangene E-Mail-Eigenschaften, falls Sie einen UTF-8-Text und einen PDF-Anhang versenden:

...
From: ...
To: ...
Message-ID: <...JavaMail.User@...>
Subject: =?UTF-8?Q?Mein_Betreff_mit_den?=
 =?UTF-8?Q?_Sonderzeichen_=C3=A4=C3=B6=C3=BC=C3=9F=E2=82=AC?=
MIME-Version: 1.0
Content-Type: multipart/mixed;
...
------=_Part_...
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Meine Test-E-Mail mit den Sonderzeichen =C3=A4=C3=B6=C3=BC=C3=9F=E2=82=AC
------=_Part_...
Content-Type: application/pdf; name=Test.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=Test.pdf
Content-Description: Test.pdf
...


Beispiele für Account-Einstellungen zu E-Mail-Providern

Provider IMAP POP3 SMTP
1 & 1 imap.1und1.de:993 (SSL) pop.1und1.de:995 (SSL) smtp.1und1.de:587 (STARTTLS)
Freenet mx.freenet.de:993 (SSL) mx.freenet.de:995 (SSL) mx.freenet.de:587 (STARTTLS)
GMX imap.gmx.net:993 (SSL) pop.gmx.net:995 (SSL) mail.gmx.net:587 (STARTTLS)
Google Mail imap.gmail.com:993 (SSL) pop.gmail.com:995 (SSL) smtp.gmail.com:465 (SSL)
Hosteurope v4-wp...webpack.hosteurope.de:143 (TLS) v4-wp...webpack.hosteurope.de:110 (TLS) v4-wp...webpack.hosteurope.de:587 (TLS)
Outlook.com imap-mail.outlook.com:993 (SSL) pop-mail.outlook.com:995 (SSL) smtp-mail.outlook.com:587 (STARTTLS)
Strato imap.strato.de: 993 (SSL/TLS) pop3.strato.de:995 (SSL/TLS) smtp.strato.de:465 (SSL/TLS)
T-Online secureimap.t-online.de:993 (SSL) securepop.t-online.de:995 (SSL) securesmtp.t-online.de:465 (SSL)
Web.de imap.web.de:993 (SSL) pop3.web.de:995 (SSL) smtp.web.de:587 (STARTTLS)
Yahoo Mail imap.mail.yahoo.com:993 (SSL) pop.mail.yahoo.com:995 (SSL) smtp.mail.yahoo.com:465 (SSL)




Weitere Themen: andere TechDocs | JSP | Netzwerkfunktionen | Webanwendungen
© 1998-2014 Torsten Horn, Aachen