Exemple de JavaMail – Envoyer un courrier en Java en utilisant SMTP

Aujourd’hui, nous examinerons un exemple de JavaMail pour envoyer des e-mails dans des programmes Java. L’envoi d’e-mails est l’une des tâches courantes dans les applications de la vie réelle, c’est pourquoi Java fournit une API robuste JavaMail que nous pouvons utiliser pour envoyer des e-mails en utilisant un serveur SMTP. L’API JavaMail prend en charge à la fois l’authentification TLS et SSL pour l’envoi d’e-mails.

Exemple de JavaMail

Aujourd’hui, nous allons apprendre comment utiliser l’API JavaMail pour envoyer des e-mails en utilisant un serveur SMTP sans authentification, avec une authentification TLS et SSL, et comment envoyer des pièces jointes et attacher et utiliser des images dans le corps de l’e-mail. Pour l’authentification TLS et SSL, j’utilise le serveur SMTP de GMail car il prend en charge les deux. Vous pouvez également choisir d’utiliser un serveur de messagerie Java en fonction des besoins de votre projet. L’API JavaMail ne fait pas partie du JDK standard, vous devrez donc la télécharger depuis son site officiel, c’est-à-dire la page d’accueil de JavaMail. Téléchargez la dernière version de l’implémentation de référence de JavaMail et incluez-la dans le chemin de construction de votre projet. Le nom du fichier JAR sera javax.mail.jar. Si vous utilisez un projet basé sur Maven, ajoutez simplement la dépendance suivante à votre projet.

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

Le programme Java pour envoyer un e-mail contient les étapes suivantes:

  1. Création de l’objet javax.mail.Session
  2. Création de l’objet javax.mail.internet.MimeMessage, nous devons définir différentes propriétés dans cet objet telles que l’adresse e-mail du destinataire, le sujet de l’e-mail, l’e-mail de réponse, le corps de l’e-mail, les pièces jointes, etc.
  3. Utilisation de javax.mail.Transport pour envoyer le message électronique.

La logique de création de session diffère en fonction du type de serveur SMTP, par exemple si le serveur SMTP ne nécessite aucune authentification, nous pouvons créer l’objet Session avec des propriétés simples tandis que s’il nécessite une authentification TLS ou SSL, alors la logique de création différera. Je vais donc créer une classe utilitaire avec quelques méthodes utilitaires pour envoyer des e-mails, puis j’utiliserai cette méthode utilitaire avec différents serveurs SMTP.

Exemple de programme JavaMail

Notre classe EmailUtil qui a une seule méthode pour envoyer un e-mail ressemble à ce qui suit, elle nécessite javax.mail.Session et quelques autres champs requis en tant qu’arguments. Pour simplifier, certains des arguments sont codés en dur mais vous pouvez étendre cette méthode pour les passer ou les lire à partir de certains fichiers de configuration.

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);
	      //Définir les en-têtes du message
	      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();
	    }
	}
}

Remarquez que je définis certaines propriétés d’en-tête dans le MimeMessage, elles sont utilisées par les clients de messagerie électronique pour afficher correctement le message électronique. Le reste du programme est simple et facile à comprendre. Maintenant, créons notre programme pour envoyer un e-mail sans authentification.

Envoyer un e-mail en Java en utilisant SMTP sans authentification

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");
	}

}

Remarquez que j’utilise Session.getInstance() pour obtenir l’objet Session en passant l’objet Properties. Nous devons définir la propriété mail.smtp.host avec l’hôte du serveur SMTP. Si le serveur SMTP ne fonctionne pas sur le port par défaut (25), vous devrez également définir la propriété mail.smtp.port. Exécutez simplement ce programme avec votre serveur SMTP sans authentification et en définissant l’identifiant de destinataire comme votre propre adresse e-mail et vous recevrez l’e-mail en un rien de temps. Le programme est simple à comprendre et fonctionne bien, mais dans la vie réelle, la plupart des serveurs SMTP utilisent une sorte d’authentification telle que l’authentification TLS ou SSL. Nous verrons donc maintenant comment créer un objet Session pour ces protocoles d’authentification.

Envoyer un e-mail en Java SMTP avec authentification TLS

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
		
                //créer un objet Authenticator à passer en argument à Session.getInstance
		Authenticator auth = new Authenticator() {
			//remplacer la méthode getPasswordAuthentication
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(fromEmail, password);
			}
		};
		Session session = Session.getInstance(props, auth);
		
		EmailUtil.sendEmail(session, toEmail,"TLSEmail Testing Subject", "TLSEmail Testing Body");
		
	}

	
}

Étant donné que j’utilise le serveur SMTP de GMail qui est accessible à tous, vous pouvez définir les variables correctes dans le programme ci-dessus et l’exécuter vous-même. Croyez-moi, ça marche !! 🙂

Exemple Java SMTP avec authentification SSL

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() {
			//remplacer la méthode getPasswordAuthentication
			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");

	}

}

Le programme est presque identique à l’authentification TLS, seules quelques propriétés sont différentes. Comme vous pouvez le voir, j’appelle d’autres méthodes de la classe EmailUtil pour envoyer une pièce jointe et une image par e-mail, mais je ne les ai pas encore définies. En fait, je les ai gardées pour les montrer plus tard et les simplifier au début du tutoriel.

Exemple JavaMail – envoyer un e-mail en Java avec une pièce jointe

Pour envoyer un fichier en pièce jointe, nous devons créer un objet javax.mail.internet.MimeBodyPart et javax.mail.internet.MimeMultipart. Ajoutez d’abord la partie du corps pour le message texte dans l’e-mail, puis utilisez FileDataSource pour attacher le fichier dans la deuxième partie du corps multipart. La méthode ressemble à ce qui suit.

/**
 * 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));
	      
         // Créer la partie du corps du message
         BodyPart messageBodyPart = new MimeBodyPart();

         // Remplir le message
         messageBodyPart.setText(body);
         
         // Créer un message multipart pour la pièce jointe
         Multipart multipart = new MimeMultipart();

         // Définir la partie du message texte
         multipart.addBodyPart(messageBodyPart);

         // La deuxième partie est la pièce jointe
         messageBodyPart = new MimeBodyPart();
         String filename = "abc.txt";
         DataSource source = new FileDataSource(filename);
         messageBodyPart.setDataHandler(new DataHandler(source));
         messageBodyPart.setFileName(filename);
         multipart.addBodyPart(messageBodyPart);

         // Envoyer les parties du message complètes
         msg.setContent(multipart);

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

Le programme peut sembler complexe à première vue, mais il est simple, il suffit de créer une partie de corps pour le message texte et une autre partie de corps pour la pièce jointe, puis de les ajouter au multipart. Vous pouvez étendre cette méthode pour joindre plusieurs fichiers également.

Exemple JavaMail – envoyer un mail en java avec image

Puisque nous pouvons créer un message de corps HTML, si le fichier image est situé sur un serveur, nous pouvons utiliser l’élément img pour les afficher dans le message. Mais parfois, nous voulons joindre l’image dans l’email et ensuite l’utiliser dans le corps de l’email lui-même. Vous avez dû voir tant d’emails qui ont des pièces jointes d’images et sont également utilisées dans le message de l’email. L’astuce est de joindre le fichier image comme toute autre pièce jointe, puis de définir l’en-tête Content-ID pour le fichier image et ensuite utiliser le même identifiant de contenu dans le corps du message de l’email avec <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));
	      
         // Créer la partie du corps du message
         BodyPart messageBodyPart = new MimeBodyPart();

         messageBodyPart.setText(body);
         
         // Créer un message multipart pour la pièce jointe
         Multipart multipart = new MimeMultipart();

         // Définir la partie du message texte
         multipart.addBodyPart(messageBodyPart);

         // La deuxième partie est la pièce jointe de l'image
         messageBodyPart = new MimeBodyPart();
         String filename = "image.png";
         DataSource source = new FileDataSource(filename);
         messageBodyPart.setDataHandler(new DataHandler(source));
         messageBodyPart.setFileName(filename);
         //L'astuce est d'ajouter ici l'en-tête content-id
         messageBodyPart.setHeader("Content-ID", "image_id");
         multipart.addBodyPart(messageBodyPart);

         //troisième partie pour afficher l'image dans le corps de l'email
         messageBodyPart = new MimeBodyPart();
         messageBodyPart.setContent("

Attached Image

" + "", "text/html"); multipart.addBodyPart(messageBodyPart); //Définir le message multipart à l'email msg.setContent(multipart); // Envoyer le message Transport.send(msg); System.out.println("EMail Sent Successfully with image!!"); }catch (MessagingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } }

Conseils de dépannage de l’API JavaMail

  1. java.net.UnknownHostException survient lorsque votre système ne parvient pas à résoudre l’adresse IP du serveur SMTP, elle peut être incorrecte ou inaccessible depuis votre réseau. Par exemple, le serveur SMTP de Gmail est smtp.gmail.com et si j’utilise smtp.google.com, je recevrai cette exception. Si le nom d’hôte est correct, essayez de pinguer le serveur via la ligne de commande pour vous assurer qu’il est accessible depuis votre système.

    pankaj@Pankaj:~/CODE$ ping smtp.gmail.com
    PING gmail-smtp-msa.l.google.com (74.125.129.108): 56 données octets
    64 octets de 74.125.129.108: icmp_seq=0 ttl=46 durée=38.308 ms
    64 octets de 74.125.129.108: icmp_seq=1 ttl=46 durée=42.247 ms
    64 octets de 74.125.129.108: icmp_seq=2 ttl=46 durée=38.164 ms
    64 octets de 74.125.129.108: icmp_seq=3 ttl=46 durée=53.153 ms
    
  2. Si votre programme est bloqué dans l’appel à la méthode send() de Transport, vérifiez que le port SMTP est correct. Si c’est le cas, utilisez telnet pour vérifier qu’il est accessible depuis votre machine, vous obtiendrez une sortie comme ci-dessous.

    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
    

C’est tout pour l’exemple de JavaMail pour envoyer des mails en Java en utilisant un serveur SMTP avec différents protocoles d’authentification, des pièces jointes et des images. J’espère que cela résoudra tous vos besoins pour envoyer des e-mails dans des programmes Java.

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