Hoje vamos analisar um Exemplo de JavaMail para enviar e-mails em programas Java. O envio de e-mails é uma das tarefas comuns em aplicações da vida real, e é por isso que o Java fornece uma API robusta de JavaMail que podemos usar para enviar e-mails usando um servidor SMTP. A API de JavaMail suporta tanto autenticação TLS quanto SSL para envio de e-mails.
Exemplo de JavaMail
Hoje vamos aprender como usar a API de JavaMail para enviar e-mails usando um servidor SMTP sem autenticação, autenticação TLS e SSL, e como enviar anexos e incorporar e usar imagens no corpo do e-mail. Para autenticação TLS e SSL, estou usando o servidor SMTP do GMail porque ele suporta ambos. Você também pode optar por usar um servidor de e-mails Java, dependendo das necessidades do seu projeto. A API de JavaMail não faz parte do JDK padrão, então você terá que baixá-la do site oficial, ou seja, da Página Inicial do JavaMail. Baixe a versão mais recente da implementação de referência do JavaMail e inclua-a no caminho de construção do seu projeto. O nome do arquivo JAR será javax.mail.jar. Se você estiver usando um projeto baseado no Maven, basta adicionar a seguinte dependência ao seu projeto.
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
Java Program para enviar e-mail contém os seguintes passos:
- Criando objeto
javax.mail.Session
- Criando objeto
javax.mail.internet.MimeMessage
, temos que definir diferentes propriedades neste objeto, como endereço de e-mail do destinatário, Assunto do E-mail, E-mail de Resposta, corpo do e-mail, anexos etc. - Usando
javax.mail.Transport
para enviar a mensagem de e-mail.
A lógica para criar a sessão difere com base no tipo de servidor SMTP, por exemplo, se o servidor SMTP não exigir nenhuma autenticação, podemos criar o objeto Session com algumas propriedades simples, enquanto que se exigir autenticação TLS ou SSL, a lógica para criar será diferente. Então vou criar uma classe utilitária com alguns métodos utilitários para enviar e-mails e depois vou usar esse método utilitário com diferentes servidores SMTP.
Exemplo de Programa JavaMail
Nossa classe EmailUtil que possui um único método para enviar e-mail é semelhante ao abaixo, requer javax.mail.Session e alguns outros campos necessários como argumentos. Para simplificar, alguns dos argumentos são codificados com valores fixos, mas você pode estender esse método para passá-los ou lê-los de alguns arquivos de configuração.
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);
//definir cabeçalhos da mensagem
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();
}
}
}
Observe que estou definindo algumas propriedades de cabeçalho no MimeMessage, elas são usadas pelos clientes de email para renderizar e exibir corretamente a mensagem de email. O resto do programa é simples e autoexplicativo. Agora, vamos criar nosso programa para enviar email sem autenticação.
Enviar Email em Java usando SMTP sem autenticação
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");
}
}
Observe que estou usando Session.getInstance() para obter o objeto Session passando o objeto Properties. Precisamos definir a propriedade mail.smtp.host com o host do servidor SMTP. Se o servidor SMTP não estiver rodando na porta padrão (25), então também será necessário definir a propriedade mail.smtp.port. Basta executar este programa com seu servidor SMTP sem autenticação e, definindo o endereço de email do destinatário como seu próprio endereço de email, e você receberá o email em pouco tempo. O programa é simples de entender e funciona bem, mas na vida real, a maioria dos servidores SMTP usa algum tipo de autenticação, como autenticação TLS ou SSL. Então, agora veremos como criar um objeto Session para esses protocolos de autenticação.
Enviar Email em Java SMTP com Autenticação 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
//criar objeto Authenticator para passar na argumentação de Session.getInstance
Authenticator auth = new Authenticator() {
//sobrescrever o método 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");
}
}
Como estou usando o servidor SMTP do Gmail, que é acessível a todos, você pode definir as variáveis corretas no programa acima e executá-lo por si mesmo. Acredite em mim, funciona!! 🙂
Exemplo de SMTP Java com Autenticação 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() {
//sobrescrever o método 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");
}
}
O programa é quase o mesmo que a autenticação TLS, apenas algumas propriedades são diferentes. Como você pode ver, estou chamando alguns outros métodos da classe EmailUtil para enviar anexo e imagem no e-mail, mas ainda não os defini. Na verdade, os mantive para mostrar mais tarde e manter o início do tutorial simples.
Exemplo JavaMail – enviar e-mail em java com anexo
Para enviar um arquivo como anexo, precisamos criar um objeto de javax.mail.internet.MimeBodyPart
e javax.mail.internet.MimeMultipart
. Primeiro adicione a parte do corpo para a mensagem de texto no e-mail e, em seguida, use FileDataSource para anexar o arquivo na segunda parte do corpo multipart. O método se parece com o abaixo.
/**
* 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));
// Criar a parte do corpo da mensagem
BodyPart messageBodyPart = new MimeBodyPart();
// Preencher a mensagem
messageBodyPart.setText(body);
// Criar uma mensagem multipart para anexo
Multipart multipart = new MimeMultipart();
// Definir a parte de mensagem de texto
multipart.addBodyPart(messageBodyPart);
// A segunda parte é o anexo
messageBodyPart = new MimeBodyPart();
String filename = "abc.txt";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Enviar as partes completas da mensagem
msg.setContent(multipart);
// Enviar mensagem
Transport.send(msg);
System.out.println("EMail Sent Successfully with attachment!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
O programa pode parecer complexo à primeira vista, mas é simples, basta criar uma parte do corpo para a mensagem de texto e outra parte para o anexo e depois adicioná-las à mensagem multipart. Você pode estender esse método para anexar vários arquivos também.
Exemplo de JavaMail – enviar email em java com imagem
Já que podemos criar mensagens de corpo HTML, se o arquivo de imagem estiver localizado em alguma localização do servidor, podemos usar o elemento img para exibi-los na mensagem. Mas às vezes queremos anexar a imagem no email e depois usá-la no corpo do próprio email. Você já deve ter visto muitos emails que têm anexos de imagem e também são usados na mensagem do email. O truque é anexar o arquivo de imagem como qualquer outro anexo e depois definir o cabeçalho Content-ID para o arquivo de imagem e depois usar o mesmo ID de conteúdo na mensagem de corpo de email com <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));
// Criar a parte do corpo da mensagem
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
// Criar uma mensagem multiparte para anexo
Multipart multipart = new MimeMultipart();
// Definir a parte de mensagem de texto
multipart.addBodyPart(messageBodyPart);
// A segunda parte é o anexo de imagem
messageBodyPart = new MimeBodyPart();
String filename = "image.png";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
// O truque é adicionar o cabeçalho content-id aqui
messageBodyPart.setHeader("Content-ID", "image_id");
multipart.addBodyPart(messageBodyPart);
// terceira parte para exibir a imagem no corpo do e-mail
messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent("Attached Image
" +
"
", "text/html");
multipart.addBodyPart(messageBodyPart);
// Definir a mensagem multiparte para a mensagem de e-mail
msg.setContent(multipart);
// Enviar mensagem
Transport.send(msg);
System.out.println("EMail Sent Successfully with image!!");
}catch (MessagingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Dicas de Solução de Problemas da API JavaMail
-
java.net.UnknownHostException
ocorre quando seu sistema não é capaz de resolver o endereço IP para o servidor SMTP, pode estar errado ou não estar acessível da sua rede. Por exemplo, o servidor SMTP do GMail é smtp.gmail.com e se eu usar smtp.google.com, receberei essa exceção. Se o nome de host estiver correto, tente pingar o servidor através da linha de comando para garantir que seja acessível do seu 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 seu programa ficar preso na chamada do método Transport send(), verifique se o número da porta SMTP está correto. Se estiver correto, use o telnet para verificar se ele é acessível da sua máquina, você receberá uma saída como a abaixo.
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
É tudo para o exemplo do JavaMail para enviar e-mail em java usando servidor SMTP com diferentes protocolos de autenticação, anexos e imagens. Espero que isso resolva todas as suas necessidades para enviar e-mails em programas java.
Source:
https://www.digitalocean.com/community/tutorials/javamail-example-send-mail-in-java-smtp