JavaMail Voorbeeld – E-mail verzenden in Java met SMTP

Vandaag zullen we een JavaMail-voorbeeld bekijken om e-mails te versturen in Java-programma’s. Het verzenden van e-mails is een van de veelvoorkomende taken in real-life toepassingen en daarom biedt Java een robuuste JavaMail API die we kunnen gebruiken om e-mails te versturen via een SMTP-server. De JavaMail API ondersteunt zowel TLS- als SSL-authenticatie voor het verzenden van e-mails.

JavaMail Voorbeeld

Vandaag zullen we leren hoe we de JavaMail API kunnen gebruiken om e-mails te versturen via een SMTP-server zonder authenticatie, met TLS- en SSL-authenticatie, en hoe we bijlagen kunnen versturen en afbeeldingen kunnen toevoegen en gebruiken in de e-mailtekst. Voor TLS- en SSL-authenticatie gebruik ik de GMail SMTP-server omdat deze beide ondersteunt. U kunt er ook voor kiezen om een Java mailsysteem te gebruiken, afhankelijk van de behoeften van uw project. De JavaMail API maakt geen deel uit van de standaard JDK, dus u moet deze downloaden van de officiële website, dat wil zeggen JavaMail Home Page. Download de nieuwste versie van de JavaMail-referentie-implementatie en voeg deze toe aan het buildpad van uw project. De naam van het jar-bestand zal javax.mail.jar zijn. Als u een Maven-gebaseerd project gebruikt, voeg dan gewoon de onderstaande afhankelijkheid toe aan uw project.

<dependency>
	<groupId>com.sun.mail</groupId>
	<artifactId>javax.mail</artifactId>
	<version>1.5.5</version>
</dependency>

Het Java-programma om e-mail te versturen bevat de volgende stappen:

  1. Het maken van het javax.mail.Session-object
  2. Het maken van het javax.mail.internet.MimeMessage-object, we moeten verschillende eigenschappen instellen in dit object zoals het e-mailadres van de ontvanger, onderwerp van de e-mail, antwoord-naar e-mail, e-mailtekst, bijlagen enz.
  3. Het gebruik van javax.mail.Transport om het e-mailbericht te verzenden.

De logica om de sessie te maken verschilt op basis van het type SMTP-server, bijvoorbeeld als de SMTP-server geen authenticatie vereist, kunnen we het Session-object maken met enkele eenvoudige eigenschappen, terwijl als het TLS- of SSL-authenticatie vereist, de logica om te maken zal verschillen. Dus ik zal een hulpprogrammaklasse maken met enkele hulpprogramma-methoden om e-mails te verzenden en dan zal ik deze hulpprogramma-methode gebruiken met verschillende SMTP-servers.

Voorbeeldprogramma JavaMail

Onze EmailUtil-klasse die een enkele methode heeft om e-mail te verzenden ziet er als volgt uit, het vereist javax.mail.Session en enkele andere vereiste velden als argumenten. Om het eenvoudig te houden, zijn enkele van de argumenten hard gecodeerd maar je kunt deze methode uitbreiden om ze door te geven of ze te lezen uit enkele configuratiebestanden.

package com.journaldev.mail;

import java.io.UnsupportedEncodingException;
import java.util.Date;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class EmailUtil {

	/**
	 * Utility method to send simple HTML email
	 * @param session
	 * @param toEmail
	 * @param subject
	 * @param body
	 */
	public static void sendEmail(Session session, String toEmail, String subject, String body){
		try
	    {
	      MimeMessage msg = new MimeMessage(session);
	      //set berichtheaders
	      msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
	      msg.addHeader("format", "flowed");
	      msg.addHeader("Content-Transfer-Encoding", "8bit");

	      msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));

	      msg.setReplyTo(InternetAddress.parse("[email protected]", false));

	      msg.setSubject(subject, "UTF-8");

	      msg.setText(body, "UTF-8");

	      msg.setSentDate(new Date());

	      msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
	      System.out.println("Message is ready");
    	  Transport.send(msg);  

	      System.out.println("EMail Sent Successfully!!");
	    }
	    catch (Exception e) {
	      e.printStackTrace();
	    }
	}
}

Merk op dat ik enkele kopteksteigenschappen instel in het MimeMessage, ze worden gebruikt door de e-mailclients om het e-mailbericht correct weer te geven en weer te geven. De rest van het programma is eenvoudig en zelfverklarend. Laten we nu ons programma maken om e-mails te verzenden zonder authenticatie.

Stuur e-mail in Java met behulp van SMTP zonder authenticatie

package com.journaldev.mail;

import java.util.Properties;

import javax.mail.Session;

public class SimpleEmail {
	
	public static void main(String[] args) {
		
	    System.out.println("SimpleEmail Start");
		
	    String smtpHostServer = "smtp.example.com";
	    String emailID = "[email protected]";
	    
	    Properties props = System.getProperties();

	    props.put("mail.smtp.host", smtpHostServer);

	    Session session = Session.getInstance(props, null);
	    
	    EmailUtil.sendEmail(session, emailID,"SimpleEmail Testing Subject", "SimpleEmail Testing Body");
	}

}

Let op dat ik Session.getInstance() gebruik om het Session-object te krijgen door het Properties-object door te geven. We moeten de eigenschap mail.smtp.host instellen met de SMTP-serverhost. Als de SMTP-server niet op de standaardpoort (25) draait, moet u ook de eigenschap mail.smtp.port instellen. Voer dit programma gewoon uit met uw SMTP-server zonder authenticatie en stel het e-mailadres van de ontvanger in als uw eigen e-mailadres en u krijgt de e-mail in een mum van tijd. Het programma is eenvoudig te begrijpen en werkt goed, maar in het echte leven gebruiken de meeste SMTP-servers een vorm van authenticatie zoals TLS- of SSL-authenticatie. Dus laten we nu zien hoe we een Session-object kunnen maken voor deze authenticatieprotocollen.

Stuur e-mail in Java SMTP met TLS-authenticatie

package com.journaldev.mail;

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;

public class TLSEmail {

	/**
	   Outgoing Mail (SMTP) Server
	   requires TLS or SSL: smtp.gmail.com (use authentication)
	   Use Authentication: Yes
	   Port for TLS/STARTTLS: 587
	 */
	public static void main(String[] args) {
		final String fromEmail = "[email protected]"; //requires valid gmail id
		final String password = "mypassword"; // correct password for gmail id
		final String toEmail = "[email protected]"; // can be any email id 
		
		System.out.println("TLSEmail Start");
		Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
		props.put("mail.smtp.port", "587"); //TLS Port
		props.put("mail.smtp.auth", "true"); //enable authentication
		props.put("mail.smtp.starttls.enable", "true"); //enable STARTTLS
		
                // Maak een Authenticator-object om door te geven aan het Session.getInstance-argument
		Authenticator auth = new Authenticator() {
			// Overschrijf de getPasswordAuthentication-methode
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(fromEmail, password);
			}
		};
		Session session = Session.getInstance(props, auth);
		
		EmailUtil.sendEmail(session, toEmail,"TLSEmail Testing Subject", "TLSEmail Testing Body");
		
	}

	
}

Aangezien ik de GMail SMTP-server gebruik die voor iedereen toegankelijk is, kunt u de juiste variabelen instellen in het bovenstaande programma en het zelf uitvoeren. Geloof me, het werkt!! 🙂

Voorbeeld van Java SMTP met SSL-authenticatie

package com.journaldev.mail;

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;

public class SSLEmail {

	/**
	   Outgoing Mail (SMTP) Server
	   requires TLS or SSL: smtp.gmail.com (use authentication)
	   Use Authentication: Yes
	   Port for SSL: 465
	 */
	public static void main(String[] args) {
		final String fromEmail = "[email protected]"; //requires valid gmail id
		final String password = "mypassword"; // correct password for gmail id
		final String toEmail = "[email protected]"; // can be any email id 
		
		System.out.println("SSLEmail Start");
		Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.gmail.com"); //SMTP Host
		props.put("mail.smtp.socketFactory.port", "465"); //SSL Port
		props.put("mail.smtp.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory"); //SSL Factory Class
		props.put("mail.smtp.auth", "true"); //Enabling SMTP Authentication
		props.put("mail.smtp.port", "465"); //SMTP Port
		
		Authenticator auth = new Authenticator() {
			// overschrijf de getPasswordAuthentication-methode
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(fromEmail, password);
			}
		};
		
		Session session = Session.getDefaultInstance(props, auth);
		System.out.println("Session created");
	        EmailUtil.sendEmail(session, toEmail,"SSLEmail Testing Subject", "SSLEmail Testing Body");

	        EmailUtil.sendAttachmentEmail(session, toEmail,"SSLEmail Testing Subject with Attachment", "SSLEmail Testing Body with Attachment");

	        EmailUtil.sendImageEmail(session, toEmail,"SSLEmail Testing Subject with Image", "SSLEmail Testing Body with Image");

	}

}

Het programma is bijna hetzelfde als TLS-authenticatie, alleen zijn sommige eigenschappen anders. Zoals je kunt zien, roep ik wat andere methoden aan uit de EmailUtil-klasse om bijlagen en afbeeldingen in e-mails te verzenden, maar ik heb ze nog niet gedefinieerd. Eigenlijk heb ik ze bewaard om later te laten zien en het simpel te houden aan het begin van de tutorial.

Voorbeeld van JavaMail – e-mail versturen in Java met bijlage

Om een bestand als bijlage te versturen, moeten we een object maken van javax.mail.internet.MimeBodyPart en javax.mail.internet.MimeMultipart. Voeg eerst het bodydeel toe voor het tekstbericht in de e-mail en gebruik vervolgens FileDataSource om het bestand toe te voegen in het tweede deel van het multipart-body. De methode ziet er als volgt uit.

/**
 * Utility method to send email with attachment
 * @param session
 * @param toEmail
 * @param subject
 * @param body
 */
public static void sendAttachmentEmail(Session session, String toEmail, String subject, String body){
	try{
         MimeMessage msg = new MimeMessage(session);
         msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
	     msg.addHeader("format", "flowed");
	     msg.addHeader("Content-Transfer-Encoding", "8bit");
	      
	     msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));

	     msg.setReplyTo(InternetAddress.parse("[email protected]", false));

	     msg.setSubject(subject, "UTF-8");

	     msg.setSentDate(new Date());

	     msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
	      
         // Maak het bericht-bodydeel
         BodyPart messageBodyPart = new MimeBodyPart();

         // Vul het bericht in
         messageBodyPart.setText(body);
         
         // Maak een multipart-bericht voor bijlage
         Multipart multipart = new MimeMultipart();

         // Stel tekstberichtdeel in
         multipart.addBodyPart(messageBodyPart);

         // Het tweede deel is de bijlage
         messageBodyPart = new MimeBodyPart();
         String filename = "abc.txt";
         DataSource source = new FileDataSource(filename);
         messageBodyPart.setDataHandler(new DataHandler(source));
         messageBodyPart.setFileName(filename);
         multipart.addBodyPart(messageBodyPart);

         // Verzend de complete berichtdelen
         msg.setContent(multipart);

         // Verzend bericht
         Transport.send(msg);
         System.out.println("EMail Sent Successfully with attachment!!");
      }catch (MessagingException e) {
         e.printStackTrace();
      } catch (UnsupportedEncodingException e) {
		 e.printStackTrace();
	}
}

Het programma kan er in het begin complex uitzien, maar het is eigenlijk eenvoudig. Maak gewoon een onderdeel voor het tekstbericht en een ander onderdeel voor de bijlage en voeg ze toe aan de multipart. Je kunt deze methode ook uitbreiden om meerdere bestanden bij te voegen.

JavaMail-voorbeeld – e-mail verzenden in Java met afbeelding

Aangezien we een HTML-bericht kunnen maken, kunnen we als het afbeeldingsbestand zich op een serverlocatie bevindt, het img-element gebruiken om ze in het bericht weer te geven. Maar soms willen we de afbeelding bij de e-mail voegen en deze vervolgens in het e-mailbericht zelf gebruiken. Je hebt vast wel eens e-mails gezien met bijgevoegde afbeeldingen die ook in het e-mailbericht worden gebruikt. De truc is om het afbeeldingsbestand bij te voegen zoals elke andere bijlage en vervolgens de Content-ID-header voor het afbeeldingsbestand in te stellen en dezelfde content-id te gebruiken in de body van het e-mailbericht met <img src='cid:image_id'>.

/**
 * Utility method to send image in email body
 * @param session
 * @param toEmail
 * @param subject
 * @param body
 */
public static void sendImageEmail(Session session, String toEmail, String subject, String body){
	try{
         MimeMessage msg = new MimeMessage(session);
         msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
	     msg.addHeader("format", "flowed");
	     msg.addHeader("Content-Transfer-Encoding", "8bit");
	      
	     msg.setFrom(new InternetAddress("[email protected]", "NoReply-JD"));

	     msg.setReplyTo(InternetAddress.parse("[email protected]", false));

	     msg.setSubject(subject, "UTF-8");

	     msg.setSentDate(new Date());

	     msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
	      
         // Maak het berichtonderdeel
         BodyPart messageBodyPart = new MimeBodyPart();

         messageBodyPart.setText(body);
         
         // Maak een multipart-bericht voor bijlage
         Multipart multipart = new MimeMultipart();

         // Stel het tekstberichtonderdeel in
         multipart.addBodyPart(messageBodyPart);

         // Het tweede onderdeel is de bijlage van de afbeelding
         messageBodyPart = new MimeBodyPart();
         String filename = "image.png";
         DataSource source = new FileDataSource(filename);
         messageBodyPart.setDataHandler(new DataHandler(source));
         messageBodyPart.setFileName(filename);
         // De truc is om hier de content-id-header toe te voegen
         messageBodyPart.setHeader("Content-ID", "image_id");
         multipart.addBodyPart(messageBodyPart);

         // Derde onderdeel voor het weergeven van de afbeelding in de e-mailbody
         messageBodyPart = new MimeBodyPart();
         messageBodyPart.setContent("

Attached Image

" + "", "text/html"); multipart.addBodyPart(messageBodyPart); // Stel het multipart-bericht in voor het e-mailbericht msg.setContent(multipart); // Verstuur het bericht Transport.send(msg); System.out.println("EMail Sent Successfully with image!!"); }catch (MessagingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } }

Tips voor het oplossen van problemen met de JavaMail API

  1. java.net.UnknownHostException treedt op wanneer uw systeem het IP-adres voor de SMTP-server niet kan oplossen, dit kan verkeerd zijn of niet toegankelijk zijn vanuit uw netwerk. Bijvoorbeeld, de SMTP-server van GMail is smtp.gmail.com en als ik smtp.google.com gebruik, zal ik deze uitzondering krijgen. Als de hostnaam correct is, probeer dan de server te pingen via de opdrachtregel om ervoor te zorgen dat deze toegankelijk is vanaf uw systeem.

    pankaj@Pankaj:~/CODE$ ping smtp.gmail.com
    PING gmail-smtp-msa.l.google.com (74.125.129.108): 56 data bytes
    64 bytes from 74.125.129.108: icmp_seq=0 ttl=46 time=38.308 ms
    64 bytes from 74.125.129.108: icmp_seq=1 ttl=46 time=42.247 ms
    64 bytes from 74.125.129.108: icmp_seq=2 ttl=46 time=38.164 ms
    64 bytes from 74.125.129.108: icmp_seq=3 ttl=46 time=53.153 ms
    
  2. Als uw programma vastzit in de Transport send() methode, controleer dan of de SMTP-poort correct is. Als het correct is, gebruik dan telnet om te controleren of het toegankelijk is vanaf uw machine, u krijgt een uitvoer zoals hieronder.

    pankaj@Pankaj:~/CODE$ telnet smtp.gmail.com 587
    Trying 2607:f8b0:400e:c02::6d...
    Connected to gmail-smtp-msa.l.google.com.
    Escape character is '^]'.
    220 mx.google.com ESMTP sx8sm78485186pab.5 - gsmtp
    HELO
    250 mx.google.com at your service
    

Dat is alles voor het JavaMail-voorbeeld om e-mails te versturen in Java met behulp van een SMTP-server met verschillende authenticatieprotocollen, bijlagen en afbeeldingen. Ik hoop dat het al uw behoeften zal oplossen voor het verzenden van e-mails in Java-programma’s.

Source:
https://www.digitalocean.com/community/tutorials/javamail-example-send-mail-in-java-smtp