Envio de E-mails com Spring Boot e SMTP do Gmail
Este documento detalha o processo de configuração e envio de e-mails em uma aplicação Spring Boot, utilizando o servidor SMTP do Gmail.
1. Habilitando o SMTP do Gmail e Gerando uma Senha de App
Para usar o SMTP do Gmail em uma aplicação externa, você precisa de uma "Senha de app" (App Password) se tiver a verificação em duas etapas ativada. É altamente recomendável ter a verificação em duas etapas ativada para maior segurança.
Passo a Passo para Gerar uma Senha de App:
- Acesse sua Conta Google: Vá para myaccount.google.com.
- Vá para Segurança: No menu lateral esquerdo, clique em "Segurança".
- Verificação em Duas Etapas: Role para baixo até a seção "Como você faz login no Google" e clique em "Verificação em duas etapas". Se ainda não estiver ativada, siga as instruções para ativá-la.
- Senhas de app: Após ativar a verificação em duas etapas, volte à tela de "Segurança" e procure por "Senhas de app". Clique nela.
- Gerar Nova Senha de App:
- Selecione "Correio" no menu suspenso "Selecionar app".
- Selecione "Outro (nome personalizado)" no menu suspenso "Selecionar dispositivo" e digite um nome como "Spring Boot Email" (opcional, apenas para identificação).
- Clique em "Gerar".
- Copie a Senha de App: Uma senha de 16 caracteres será exibida em uma caixa amarela. Copie essa senha e guarde-a em um local seguro. Esta será a senha que você usará na sua aplicação Spring Boot, e não a senha da sua conta Google.
Observação: Se você não quiser ativar a verificação em duas etapas, teria que ativar a opção "Acesso a apps menos seguros" (Less secure app access) nas configurações de segurança do Google. No entanto, essa opção é descontinuada para contas pessoais a partir de 30 de maio de 2022 e não é recomendada por razões de segurança. Sempre prefira usar as "Senhas de app".
2. Configurando o Projeto Spring Boot
2.1. Adicionar Dependência do Spring Mail
Adicione a dependência spring-boot-starter-mail ao seu arquivo pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
2.2. Configurar as Propriedades do Gmail no application.properties
No arquivo src/main/resources/application.properties adicione as seguintes configurações:
application.properties:
# Propriedades do Servidor SMTP do Gmail
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=${EMAIL_USER} # Seu endereço de e-mail do Gmail em uma variável de ambiente
spring.mail.password=${EMAIL_SENHA} # A senha de app gerada anteriormente em uma variável de ambiente
# Propriedades adicionais para SMTP seguro (TLS)
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
organize suas variáveis de ambiente
3. Criando o Serviço de E-mail
Crie uma classe de serviço para lidar com o envio de e-mails.
// src/main/java/com/example/emaildemo/service/EmailService.java
package com.example.emaildemo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
@Service
public class EmailService {
@Autowired
private JavaMailSender mailSender;
/**
* Envia um e-mail simples.
* @param to O destinatário do e-mail.
* @param subject O assunto do e-mail.
* @param text O corpo do e-mail.
*/
public void sendSimpleEmail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("seu_email@gmail.com"); // Pode ser lido da configuração do application.properties
message.setTo(to);
message.setSubject(subject);
message.setText(text);
mailSender.send(message);
System.out.println("E-mail enviado com sucesso para: " + to);
}
// Você pode adicionar métodos para enviar e-mails com HTML, anexos, etc.
// Exemplo de envio de e-mail com HTML (requer MimeMessageHelper)
/*
import jakarta.mail.internet.MimeMessage;
import org.springframework.mail.javamail.MimeMessageHelper;
public void sendHtmlEmail(String to, String subject, String htmlContent) {
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); // true para multipart/mixed
helper.setFrom("seu_email@gmail.com");
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlContent, true); // true indica que o conteúdo é HTML
mailSender.send(message);
System.out.println("E-mail HTML enviado com sucesso para: " + to);
} catch (jakarta.mail.MessagingException e) {
e.printStackTrace();
// Lide com a exceção
}
}
*/
}
ThymeLeaf: Adicionalmente, se quiser enviar emails em html rico, pode usar uma template engine como o Thymeleaf
5. Considerações Importantes e Melhores Práticas
- Segurança das Credenciais:
- Nunca coloque credenciais diretamente no código-fonte em um ambiente de produção.
- Para ambientes de produção, utilize variáveis de ambiente, Spring Cloud Config, HashiCorp Vault ou outros serviços de gerenciamento de segredos para injetar as credenciais.
- Se estiver usando Docker, você pode usar segredos do Docker.
- Tratamento de Exceções: Implemente um tratamento de exceções robusto para lidar com falhas no envio de e-mails (ex: rede, autenticação, etc.).
- Logs: Configure logs para registrar o status do envio de e-mails, incluindo sucesso e falhas, para fins de depuração e auditoria.
- Assincronismo: Para evitar bloquear o thread principal da sua aplicação (especialmente em requisições web), considere enviar e-mails de forma assíncrona usando
@Asynce@EnableAsyncem sua classe de configuração principal.- Adicione
@EnableAsyncna sua classe principal (a que tem@SpringBootApplication). - Adicione
@Asyncno métodosendSimpleEmaildoEmailService.
- Adicione
- Modelos de E-mail (Templates): Para e-mails mais complexos ou com formatação HTML, use bibliotecas de templates como Thymeleaf, FreeMarker ou Mustache para criar modelos de e-mail e preenchê-los dinamicamente.
- Configurações de Produção: Em produção, verifique se seu firewall permite a saída de conexões na porta 587 (ou 465 para SSL).
- Limites do Gmail: Esteja ciente dos limites de envio diários do Gmail (geralmente 500 e-mails por dia para contas pessoais). Para maiores volumes, considere serviços de e-mail transacionais como SendGrid, Mailgun, AWS SES, etc.
Configurando as variáveis de ambiente
Setar variáveis de ambiente é crucial para manter credenciais seguras e flexibilizar as configurações da sua aplicação Spring Boot em diferentes ambientes. Abaixo, uma explicação concisa de como fazer isso para EMAIL_USER e EMAIL_SENHA em Windows, macOS e Docker Compose.
Windows
No Windows, você pode definir variáveis de ambiente temporariamente via linha de comando ou permanentemente através das configurações do sistema.
Temporariamente (para a sessão do terminal atual):
Abra o Prompt de Comando ou PowerShell e use:
set EMAIL_USER=seu_email@gmail.com
set EMAIL_SENHA=sua_senha_de_app
Ou no PowerShell:
$env:EMAIL_USER="seu_email@gmail.com"
$env:EMAIL_SENHA="sua_senha_de_app"
Em seguida, execute sua aplicação Spring Boot a partir do mesmo terminal.
Permanentemente (Sistema):
- Pesquise por "Variáveis de Ambiente" no menu Iniciar e selecione "Editar as variáveis de ambiente do sistema".
- Na janela "Propriedades do Sistema", clique em "Variáveis de Ambiente...".
- Na seção "Variáveis de usuário para
" ou "Variáveis do sistema", clique em "Novo..." para adicionar EMAIL_USEReEMAIL_SENHAcom seus respectivos valores. - Clique em "OK" em todas as janelas para salvar as alterações. Pode ser necessário reiniciar o sistema ou o terminal para que as alterações entrem em vigor.
macOS
No macOS, as variáveis de ambiente podem ser definidas temporariamente na sessão do terminal ou adicionadas aos arquivos de configuração do shell para serem persistentes.
Temporariamente (para a sessão do terminal atual):
Abra o Terminal e use:
export EMAIL_USER="seu_email@gmail.com"
export EMAIL_SENHA="sua_senha_de_app"
Em seguida, execute sua aplicação Spring Boot a partir do mesmo terminal.
Permanentemente (Perfil do Usuário):
Para que as variáveis sejam carregadas automaticamente a cada nova sessão do terminal, adicione as linhas export a um dos seguintes arquivos no seu diretório home:
~/.bash_profile(se você usa Bash como shell padrão)~/.zshrc(se você usa Zsh como shell padrão, que é o padrão no macOS Catalina e posterior)
Exemplo para ~/.zshrc:
echo 'export EMAIL_USER="seu_email@gmail.com"' >> ~/.zshrc
echo 'export EMAIL_SENHA="sua_senha_de_app"' >> ~/.zshrc
source ~/.zshrc # Para aplicar as mudanças imediatamente
Docker Compose
No Docker Compose, você pode definir variáveis de ambiente de algumas maneiras no seu arquivo docker-compose.yml. A forma mais comum e recomendada para credenciais é usar um arquivo .env.
Usando um arquivo .env (Recomendado para credenciais):
- Crie um arquivo chamado
.envno mesmo diretório do seudocker-compose.yml. -
Adicione suas variáveis de ambiente a este arquivo, uma por linha:
# .env EMAIL_USER=seu_email@gmail.com EMAIL_SENHA=sua_senha_de_app -
No seu arquivo
docker-compose.yml, referencie essas variáveis. O Docker Compose irá automaticamente carregar variáveis de um arquivo.envno mesmo diretório.# docker-compose.yml version: '3.8' services: minha-app-spring: image: sua-imagem-spring-boot:latest # Ou use build: . se for construir a imagem ports: - "8080:8080" environment: # Estas variáveis serão lidas do arquivo .env - EMAIL_USER=${EMAIL_USER} - EMAIL_SENHA=${EMAIL_SENHA} -
Execute seu serviço Docker Compose:
docker-compose up -d.
Alternativa (menos recomendada para credenciais sensíveis em controle de versão):
Você também pode definir as variáveis diretamente no docker-compose.yml na seção environment, mas isso expõe os valores no arquivo.
# docker-compose.yml
services:
minha-app-spring:
image: sua-imagem-spring-boot:latest
ports:
- "8080:8080"
environment:
EMAIL_USER: seu_email@gmail.com
EMAIL_SENHA: sua_senha_de_app # Evite isso em produção
Sempre prefira o método do arquivo .env e certifique-se de adicioná-lo ao seu .gitignore para evitar que suas credenciais sejam versionadas.