Oggi esamineremo un esempio di JavaMail per inviare email nei programmi Java. L’invio di email è una delle attività comuni nelle applicazioni della vita reale ed è per questo che Java fornisce una robusta API JavaMail che possiamo utilizzare per inviare email tramite il server SMTP. L’API JavaMail supporta sia l’autenticazione TLS che SSL per l’invio di email.
Esempio di JavaMail
Oggi impareremo come utilizzare l’API JavaMail per inviare email tramite il server SMTP senza autenticazione, con autenticazione TLS e SSL e come inviare allegati e allegare e utilizzare immagini nel corpo dell’email. Per l’autenticazione TLS e SSL, sto utilizzando il server SMTP di GMail perché supporta entrambi. Puoi anche optare per un server di posta Java in base alle esigenze del tuo progetto. L’API JavaMail non fa parte del JDK standard, quindi dovrai scaricarlo dal suo sito ufficiale, ovvero Pagina principale di JavaMail. Scarica l’ultima versione dell’implementazione di riferimento di JavaMail e includila nel percorso di build del tuo progetto. Il nome del file jar sarà javax.mail.jar. Se stai utilizzando un progetto basato su Maven, aggiungi semplicemente la dipendenza seguente al tuo progetto.
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
Il programma Java per inviare email contiene i seguenti passaggi:
- Creazione dell’oggetto
javax.mail.Session
- Creazione dell’oggetto
javax.mail.internet.MimeMessage
, dobbiamo impostare diverse proprietà in questo oggetto come l’indirizzo email del destinatario, l’oggetto dell’email, l’email di risposta, il corpo dell’email, gli allegati, ecc. - Utilizzo di
javax.mail.Transport
per inviare il messaggio email.
La logica per creare la sessione differisce in base al tipo di server SMTP, ad esempio se il server SMTP non richiede alcuna autenticazione possiamo creare l’oggetto Session con alcune proprietà semplici mentre se richiede l’autenticazione TLS o SSL, allora la logica per creare sarà diversa. Quindi creerò una classe utility con alcuni metodi di utilità per inviare email e poi userò questo metodo di utilità con diversi server SMTP.
Esempio di programma JavaMail
La nostra classe EmailUtil che ha un singolo metodo per inviare email appare come segue, richiede javax.mail.Session e alcuni altri campi richiesti come argomenti. Per mantenere la semplicità, alcuni degli argomenti sono codificati ma è possibile estendere questo metodo per passarli o leggerli da alcuni file di configurazione.
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);
//imposta gli header del messaggio
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();
}
}
}
Nota che sto impostando alcune proprietà dell’header nel MimeMessage, sono utilizzate dai client di posta elettronica per visualizzare correttamente il messaggio email. Il resto del programma è semplice e autoesplicativo. Ora creiamo il nostro programma per inviare email senza autenticazione.
Invia posta in Java usando SMTP senza autenticazione
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");
}
}
Nota che sto utilizzando Session.getInstance() per ottenere l’oggetto Session passando l’oggetto Properties. Dobbiamo impostare la proprietà mail.smtp.host con l’host del server SMTP. Se il server SMTP non è in esecuzione sulla porta predefinita (25), allora sarà necessario impostare anche la proprietà mail.smtp.port. Basta eseguire questo programma con il tuo server SMTP senza autenticazione e impostando l’indirizzo email del destinatario come il tuo indirizzo email e otterrai l’email in poco tempo. Il programma è semplice da capire e funziona bene, ma nella vita reale la maggior parte dei server SMTP utilizza qualche tipo di autenticazione come autenticazione TLS o SSL. Quindi vedremo ora come creare un oggetto Session per questi protocolli di autenticazione.
Invia Email in Java SMTP con Autenticazione 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
//crea oggetto Authenticator da passare come argomento a Session.getInstance
Authenticator auth = new Authenticator() {
//sovrascrivi il metodo 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");
}
}
Dato che sto usando il server SMTP di GMail che è accessibile a tutti, puoi impostare le variabili corrette nel programma sopra e eseguirlo tu stesso. Credimi, funziona!! 🙂
Esempio di Java SMTP con autenticazione 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() {
//sovrascrivere il metodo 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");
}
}
Il programma è quasi identico all’autenticazione TLS, solo alcune proprietà sono diverse. Come puoi vedere, sto chiamando alcuni altri metodi dalla classe EmailUtil per inviare l’allegato e l’immagine via email, ma non li ho ancora definiti. In realtà li ho mantenuti per mostrarli in seguito e mantenerlo semplice all’inizio del tutorial.
Esempio di JavaMail – invio di email in Java con allegato
Per inviare un file come allegato, è necessario creare un oggetto di javax.mail.internet.MimeBodyPart
e javax.mail.internet.MimeMultipart
. Prima aggiungi la parte del corpo per il messaggio di testo nell’email e quindi usa FileDataSource per allegare il file nella seconda parte del corpo multipart. Il metodo assomiglia a quello sotto.
/**
* 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));
// Crea la parte del corpo del messaggio
BodyPart messageBodyPart = new MimeBodyPart();
// Compila il messaggio
messageBodyPart.setText(body);
// Crea un messaggio multipart per l'allegato
Multipart multipart = new MimeMultipart();
// Imposta la parte del messaggio di testo
multipart.addBodyPart(messageBodyPart);
// La seconda parte è l'allegato
messageBodyPart = new MimeBodyPart();
String filename = "abc.txt";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Invia le parti complete del messaggio
msg.setContent(multipart);
// Invia il messaggio
Transport.send(msg);
System.out.println("EMail Sent Successfully with attachment!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Il programma potrebbe sembrare complesso a prima vista ma è semplice, basta creare una parte del corpo per il messaggio di testo e un’altra parte del corpo per l’allegato e quindi aggiungerle al multipart. È possibile estendere questo metodo per allegare anche più file.
Esempio di JavaMail – invia email in Java con immagine
Dato che possiamo creare un corpo messaggio HTML, se il file immagine si trova in qualche posizione del server possiamo utilizzare l’elemento img per mostrarlo nel messaggio. Ma a volte vogliamo allegare l’immagine nell’email e poi usarla nel corpo dell’email stesso. Avrai visto tante email che hanno allegati di immagini e vengono anche utilizzate nel messaggio dell’email. Il trucco è allegare il file immagine come qualsiasi altro allegato e quindi impostare l’intestazione Content-ID per il file immagine e poi utilizzare lo stesso ID contenuto nel corpo del messaggio email con <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));
// Crea la parte del corpo del messaggio
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
// Crea un messaggio multipart per l'allegato
Multipart multipart = new MimeMultipart();
// Imposta la parte del messaggio di testo
multipart.addBodyPart(messageBodyPart);
// La seconda parte è l'allegato dell'immagine
messageBodyPart = new MimeBodyPart();
String filename = "image.png";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
// Il trucco è aggiungere l'intestazione content-id qui
messageBodyPart.setHeader("Content-ID", "image_id");
multipart.addBodyPart(messageBodyPart);
// Terza parte per visualizzare l'immagine nel corpo dell'email
messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent("Attached Image
" +
"
", "text/html");
multipart.addBodyPart(messageBodyPart);
// Imposta il messaggio multipart nel messaggio email
msg.setContent(multipart);
// Invia il messaggio
Transport.send(msg);
System.out.println("EMail Sent Successfully with image!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Suggerimenti per la risoluzione dei problemi di JavaMail API
-
java.net.UnknownHostException
si verifica quando il sistema non è in grado di risolvere l’indirizzo IP del server SMTP, potrebbe essere errato o non accessibile dalla tua rete. Ad esempio, il server SMTP di GMail è smtp.gmail.com e se uso smtp.google.com, otterrò questa eccezione. Se il nome host è corretto, prova a pingare il server tramite la riga di comando per assicurarti che sia accessibile dal tuo sistema.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
-
Se il tuo programma è bloccato nella chiamata del metodo send() di Transport, controlla che la porta SMTP sia corretta. Se è corretta, utilizza telnet per verificare che sia accessibile dal tuo computer, otterrai un output come quello riportato di seguito.
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
Questo è tutto per l’esempio di JavaMail per inviare email in Java utilizzando un server SMTP con diversi protocolli di autenticazione, allegati e immagini. Spero che risolva tutte le tue esigenze per l’invio di email nei programmi Java.
Source:
https://www.digitalocean.com/community/tutorials/javamail-example-send-mail-in-java-smtp