Questa è una classettina che mi sono scritto per le applicazioni "veloci":
codice:
import java.io.FileInputStream;
import java.util.*;
import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import org.apache.log4j.*;
public class MailerUtility {
// Logger
private static Logger logger = Logger.getLogger(MailerUtility.class.getName());
// User Authenticator
private class UserAuthenticator extends Authenticator {
private String user;
private String pass;
public UserAuthenticator(String user, String pass) {
this.user = user;
this.pass = pass;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass);
}
}
// Classe che rappresenta un allegato
private class Allegato {
private String nomeAllegato;
private String mimeType;
private String cid;
private byte[] fileAllegato;
public Allegato(String nomeAllegato, String mimeType, String cid, byte[] fileAllegato) {
this.nomeAllegato = nomeAllegato;
this.mimeType = mimeType;
this.cid = cid;
this.fileAllegato = fileAllegato;
}
public String getNomeAllegato() {
return nomeAllegato;
}
public String getMimeType() {
return mimeType;
}
public String getCid() {
return cid;
}
public byte[] getFileAllegato() {
return fileAllegato;
}
}
private String mailConfig; // Percorso al file di configurazione
private String subject; // Oggetto della mail
private String txtMessage; // Corpo del messaggio in formato testo
private String htmlMessage; // Corpo del messaggio in formato HTML
private ArrayList<String> toAddress; // Elenco destinatari principali
private ArrayList<String> ccAddress; // Elenco destinatari in copia
private ArrayList<String> bccAddress; // Elenco destinatari in copia nascosta
private ArrayList<String> replyTo; // Elenco destinatari delle risposte
private ArrayList<Allegato> attachments; // Elenco allegati
private boolean retrySend; // Flag che indica che può essere tentato il reinvio in caso di errore
private int numRetry; // Numero di tentativi effettuati di reinvio
public MailerUtility(String mailConfig) {
this.mailConfig = mailConfig;
subject = "";
txtMessage = "";
htmlMessage = "";
retrySend = false;
numRetry = 0;
toAddress = new ArrayList<String>();
ccAddress = new ArrayList<String>();
bccAddress = new ArrayList<String>();
replyTo = new ArrayList<String>();
attachments = new ArrayList<Allegato>();
}
public void setSubject(String subject) {
this.subject = subject;
}
public void addRecipient(String recipient) {
toAddress.add(recipient);
}
public void addCopyRecipient(String copyRec) {
ccAddress.add(copyRec);
}
public void addHiddenCopyRecipient(String hideRec) {
bccAddress.add(hideRec);
}
public void addReplyTo(String addr) {
replyTo.add(addr);
}
public void addAttachment(byte[] f, String newName, String mimeType, String cid) {
attachments.add(new Allegato(newName, mimeType, cid, f));
}
public void setTextMessage(String txtMsg) {
this.txtMessage = txtMsg;
}
public void setHtmlMessage(String htmlMessage) {
this.htmlMessage = htmlMessage;
}
public boolean sendMail() {
boolean ret = false;
retrySend = false;
try {
Properties specProps = new Properties();
// Impostiamo un timeOut per la connessione
// 30 secondi sono più che sufficienti
specProps.put("mail.smtp.connectiontimeout", "30000");
specProps.put("mail.smtp.timeout", "30000");
// Andiamo a leggere la configurazione per la connessione al server SMTP
specProps.load(new FileInputStream(mailConfig));
String user = specProps.getProperty("nomeutente");
String pass = specProps.getProperty("password");
specProps.remove("nomeutente");
specProps.remove("password");
UserAuthenticator userAuthenticator = new UserAuthenticator(user, pass);
Session session = Session.getInstance(specProps, userAuthenticator);
MimeMessage message = new MimeMessage(session);
InternetAddress iaFrom = new InternetAddress( user );
message.setFrom( iaFrom );
if (!replyTo.isEmpty()) {
Address[] addrReply = new Address[replyTo.size()];
for (int i = 0; i < replyTo.size(); i++) {
addrReply[i] = new InternetAddress(replyTo.get(i));
}
message.setReplyTo(addrReply);
}
// Aggiungo i destinatari visibili
for (String rec : toAddress) {
message.addRecipient(Message.RecipientType.TO, new InternetAddress(rec));
}
// Aggiungo i destinatari in copia
for (String rec : ccAddress) {
message.addRecipient(Message.RecipientType.CC, new InternetAddress(rec));
}
// Aggiungo i destinatari in copia nascosta
for (String rec : bccAddress) {
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(rec));
}
message.setSubject(subject);
componiMessaggio(message);
Transport.send(message);
ret = true;
} catch (AuthenticationFailedException afe) {
if (numRetry < 2) {
logger.error("Errore autenticazione, ma dovrebbe essere un falso allarme! Riprovo.", afe);
retrySend = true;
numRetry++;
} else {
logger.error("Sembra esserci per davvero un problema di autenticazione.", afe);
retrySend = false;
numRetry++;
}
} catch (AddressException ae) {
logger.error("Errore invio mail a causa di un indirizzo errato.", ae);
} catch (MessagingException me) {
if (numRetry < 2) {
if ( me.getMessage().startsWith("Exception reading response") ) {
logger.error("Errore di timeout in lettura response dal server, ma potrebbe essere un falso allarme! Riprovo.", me);
retrySend = true;
numRetry++;
} else {
logger.error("Sembra esserci per davvero un problema di comunicazione col server di posta.", me);
retrySend = false;
numRetry++;
}
} else {
logger.error("Sembra esserci per davvero un problema di comunicazione col server di posta.", me);
retrySend = false;
numRetry++;
}
} catch (Exception e) {
logger.error("Errore invio mail generico.", e);
}
return ret;
}
public boolean canRetrySend() {
return retrySend;
}
private void componiMessaggio(MimeMessage message) throws Exception {
Multipart multipart = new MimeMultipart();
// Se c'è anche una parte HTML, devo generare un multipart alternative
if ((htmlMessage != null) && !"".equals(htmlMessage)) {
MimeBodyPart altBody = new MimeBodyPart();
Multipart alternative = new MimeMultipart("alternative");
MimeBodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText(txtMessage, "ISO-8859-15");
MimeBodyPart htmlBodyPart = new MimeBodyPart();
htmlBodyPart.setContent(htmlMessage, "text/html; charset=utf-8");
htmlBodyPart.addHeader("Content-Transfer-Encoding", "7bit");
alternative.addBodyPart(textBodyPart);
alternative.addBodyPart(htmlBodyPart);
altBody.setContent(alternative);
multipart.addBodyPart(altBody);
} else {
// Creo il corpo del messaggio con il testo
BodyPart bodyPart = new MimeBodyPart();
((MimeBodyPart) bodyPart).setText(txtMessage, "ISO-8859-15");
multipart.addBodyPart(bodyPart);
}
// Se ci sono allegati, li allego ;-)
for (Allegato al : attachments) {
ByteArrayDataSource bds = new ByteArrayDataSource(al.getFileAllegato(), al.getMimeType());
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setDataHandler( new DataHandler(bds) );
bodyPart.setFileName(al.getNomeAllegato());
if ( !"".equals(al.getCid().trim()) ) {
bodyPart.setDisposition( MimeBodyPart.INLINE );
bodyPart.setHeader("Content-ID","<" + al.getCid().trim() + ">");
}
multipart.addBodyPart(bodyPart);
}
// Aggiungo il Multipart al messaggio
message.setContent(multipart);
}
}
In questo caso ho usato Log4J per il logging, ma se non ti serve puoi tirarlo via.
Utilizza un file di properties per la configurazione, così:
codice:
mail.smtp.host = smtp-mail.outlook.com
mail.smtp.starttls.enable = true
mail.smtp.auth = true
mail.smtp.port = 587
mail.smtp.connectiontimeout = 30000
mail.smtp.timeout = 30000
nomeutente = <tuo indirizzo email>
password = <tua password>
Qui un esempio d'uso:
codice:
// Creo l'istanza passandogli il percorso al file di properties
MailerUtility mu = new MailerUtility("/percorso/al/tuo/file/di/properties");
// Aggiungo tutti i destinatari principali (sono facoltativi)
mu.addRecipient("pippo@pluto.it");
// Aggiungo tutti i destinatari in copia (sono facoltativi)
mu.addCopyRecipient("paperone@pluto.it");
// Aggiungo i destinatari in copia nascosta (sono facoltativi)
mu.addHiddenCopyRecipient("paperina@pluto.it");
// Aggiunto l'indirizzo per il Reply-to (è facoltativo)
mu.addReplyTo("paperino@pluto.it");
// Oggetto della mail
mu.setSubject("Bla bla bla");
// Il corpo della mail in formato solo testo (è facoltativo, se c'è l'HTML)
mu.setTextMessage("Corpo della mail");
// Il corpo della mail in formato HTML (è facoltativo se c'è il formato testo)
mu.setHtmlMessage("<p>Corpo della mail</p>");
// Eventuali allegati
byte[] fileData = ... // Leggo il file e ottengo un array di byte
mu.addAttachment(fileData, "MioFile.PDF", "application/pdf", "");
// Invio la mail
boolean esito = false;
do {
esito = mu.sendMail();
if ( !esito && mu.canRetrySend()) {
try {
Thread.sleep( 10000L ); // Attendiamo 10 secondi prima di ritentare l'invio
} catch (InterruptedException ie) { }
}
} while(!esito && mu.canRetrySend());
Questo codice (in realtà è una semplificazione, ma non cambia) lo sto usando in produzione ormai da 2 anni (quando abbiamo fatto il passaggio a Office 365).
Ciao.