Skip to content

Instantly share code, notes, and snippets.

@thaniaclair
Last active December 17, 2015 05:49
Show Gist options
  • Save thaniaclair/5561126 to your computer and use it in GitHub Desktop.
Save thaniaclair/5561126 to your computer and use it in GitHub Desktop.
Enviador de emails Java.
import java.io.File;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
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;
import javax.mail.util.ByteArrayDataSource;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import br.com.sebrae.MailProperties;
import br.com.sebrae.SISProperties;
import br.com.sebrae.model.Usuario;
/**
* Enviador de emails.
* @author thania.clair
*/
public class MailSender {
private static final Logger logger = Logger.getLogger(MailSender.class);
private static final String RETURN_PATH_LABEL = "Return-Path";
private static final String UNSUBSCRIBE_LABEL = "List-Unsubscribe";
private static final String CHARSET = "UTF-8";
private ContentType contentType = ContentType.HTML;
private Integer id;
private String to;
private String subject;
private String content;
private List<File> files;
private Map<String, byte[]> bytesMap;
/**
* Construtor para envio de email.
* @param to destinatário do email.
* @param subject assunto do email.
* @param content corpo do email.
*/
public MailSender(String to, String subject, String content) {
this.to = to;
this.subject = subject;
this.content = content;
}
/**
* Construtor para envio de email.
* @param to destinatário do email.
* @param subject assunto do email.
* @param content corpo do email.
* @param files lista de arquivos de anexo.
*/
public MailSender(String to, String subject, String content, List<File> files) {
this(to, subject, content);
this.files = files;
}
/**
* Construtor para envio de email.
* @param to destinatário do email.
* @param subject assunto do email.
* @param content corpo do email.
* @param file arquivo de anexo.
*/
public MailSender(String to, String subject, String content, File file) {
this(to, subject, content, Arrays.asList(file));
}
/**
* Carrega uma {@link Session} para enviar email.
* @return {@link Session}.
*/
public Session getSession() {
Session session = null;
Properties properties = MailProperties.getProperties();
if (MailProperties.hasEnableAuth()) {
String username = MailProperties.getUser();
String password = MailProperties.getPassword();
PasswordAuthenticator pAuthenticator = new PasswordAuthenticator(username, password);
MailProperties.setSubmitter(username);
session = Session.getInstance(properties, pAuthenticator);
} else session = Session.getDefaultInstance(properties, null);
return session;
}
/**
* Envia o email de acordo com as configurações no arquivo de propriedades e atributos.
*/
public void send() {
if (!hasRequiredFields())
throw new IllegalArgumentException("Destinatário, assunto e corpo de email são obrigatórios para enviar e-mail!");
if (SISProperties.isNotTipoAmbienteProducao()) to = SISProperties.getEmailNotificacao();
String from = MailProperties.getFrom();
String returnPath = MailProperties.getReturnPath();
try
{
Session session = getSession();
MimeMessage message = new MimeMessage(session);
if (this.id != null) message.addHeader(UNSUBSCRIBE_LABEL, getUnsubscribeURL());
message.addHeader(RETURN_PATH_LABEL, "<" + returnPath + ">");
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSentDate(Calendar.getInstance().getTime());
message.setSubject(subject, CHARSET);
if (hasAttachment()) message.setContent(createMultipart());
else message.setContent(content, getContentType());
Transport.send(message);
}
catch (Exception e)
{
logger.error("Problemas para enviar e-mail para " + to + ". Erro: " + e.getMessage());
}
}
/**
* Cria um {@link Multipart} com o conteúdo e os {@link File}s para anexar.
* @return {@link Multipart}.
* @throws MessagingException
*/
private Multipart createMultipart() throws MessagingException {
// Parte 1: texto de conteúdo.
Multipart mp = new MimeMultipart();
MimeBodyPart mbp = new MimeBodyPart();
mbp.setContent(content, getContentType());
mp.addBodyPart(mbp);
// Parte 2: os arquivos de anexo.
if (hasFileAttachment()) {
for (File file : files) mp.addBodyPart(createMimeBodyPart(file));
}
if (hasBytesAttachment()) {
for (Map.Entry<String, byte[]> entry : bytesMap.entrySet())
mp.addBodyPart(createMimeBodyPart(entry.getKey(), entry.getValue()));
}
return mp;
}
/**
* Cria um {@link MimeBodyPart} para o {@link File} especificado.
* @param file {@link File}.
* @return {@link MimeBodyPart}.
* @throws MessagingException
*/
private MimeBodyPart createMimeBodyPart(File file) throws MessagingException {
MimeBodyPart fmbp = new MimeBodyPart();
DataSource source = new FileDataSource(file);
fmbp.setDataHandler(new DataHandler(source));
fmbp.setFileName(file.getName());
return fmbp;
}
/**
* Cria um {@link MimeBodyPart} para o {@link File} especificado.
* @param filename nome do arquivo a ser colocado como anexo.
* @param bytes bytes para anexar.
* @return {@link MimeBodyPart}.
* @throws MessagingException
*/
private MimeBodyPart createMimeBodyPart(String filename, byte[] bytes) throws MessagingException {
MimeBodyPart fmbp = new MimeBodyPart();
String mimeType = new MimeTypeGenerator(filename).getContentType();
DataSource source = new ByteArrayDataSource(bytes, mimeType);
fmbp.setDataHandler(new DataHandler(source));
fmbp.setFileName(filename);
return fmbp;
}
/**
* Recupera uma URL para descadastrar o {@link Usuario} do recebimento de emails.
* @return URL para descadastrar {@link Usuario}.
*/
private String getUnsubscribeURL() {
if (this.id == null) return null;
return SISProperties.getURLRoot() + "/inicio/desinscreverUsuario?idUsuario=" + this.id;
}
/**
* @return <code>true</code> se tem anexos, <code>false</code> caso contrário.
*/
private boolean hasAttachment() {
return hasFileAttachment() || hasBytesAttachment();
}
/**
* @return <code>true</code> se tem anexos em formato de arquivo, <code>false</code> caso contrário.
*/
private boolean hasFileAttachment() {
return (files != null && !files.isEmpty());
}
/**
* @return <code>true</code> se tem anexos em bytes, <code>false</code> caso contrário.
*/
private boolean hasBytesAttachment() {
return (bytesMap != null && !bytesMap.isEmpty());
}
/**
* @return o content type do e-mail.
*/
private String getContentType() {
return contentType.getType() + "; charset=" + CHARSET;
}
/**
* @return <code>true</code> se os campos obrigatórios foram enviados, <code>false</code> caso
* contrário.
*/
private boolean hasRequiredFields() {
return StringUtils.isNotBlank(to) && StringUtils.isNotBlank(subject) && StringUtils.isNotBlank(content);
}
public void setPlainContentType() {
contentType = ContentType.TXT;
}
public void setContentType(ContentType contentType) {
this.contentType = contentType;
}
/**
* Carrega um item no mapa de bytes para enviar como anexo.
* @param filename nome do arquivo.
* @param bytes array de bytes.
*/
public void putBytesEntry(String filename, byte[] bytes) {
if (bytesMap == null) bytesMap = new HashMap<String, byte[]>();
bytesMap.put(filename, bytes);
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<File> getFiles() {
return files;
}
public void setFiles(List<File> files) {
this.files = files;
}
public Map<String, byte[]> getBytesMap() {
return bytesMap;
}
public void setBytesMap(Map<String, byte[]> bytesMap) {
this.bytesMap = bytesMap;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
/**
* {@link Authenticator} que necessita de usuário e senha.
* @author thania.clair
*/
private class PasswordAuthenticator extends Authenticator {
private PasswordAuthentication authentication;
public PasswordAuthenticator(String username, String password) {
authentication = new PasswordAuthentication(username, password);
}
protected PasswordAuthentication getPasswordAuthentication() {
return authentication;
}
}
/**
* Enumeração dos tipos de conteúdo para envio de email.
* @author thania.clair
*/
public enum ContentType {
TXT("text/plain"), HTML("text/html");
private String type;
private ContentType(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment