DEV Community

Henrique Ferreira
Henrique Ferreira

Posted on

1

Criando uma API com Spring Boot para o envio de e-mail

Neste post, vamos criar uma simples API Rest para enviar um e-mail. Eu irei utilizar o Spring Boot e o Mailtrap para fazer essa simulação de envio de e-mail. Preparado?

Come to my Dojo!

Eu irei utilizar o site https://start.spring.io/ para gerar um projeto Spring Boot para mim já com as dependências necessárias. Segue a imagem abaixo:

Configurações do projeto no site do spring boot - spring initializr

Após isso, crie uma conta no Mailtrap. Em Inboxes, você consegue ver as credenciais do SMTP como port, username e password. Essas informações serão necessárias para o projeto. Segue a imagem abaixo:

Credenciais SMTP do Mailtrap

No projeto, adicione essas configurações no application.properties:

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=587
spring.mail.username= <adicione o username>
spring.mail.password= <adicione o password>
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
Enter fullscreen mode Exit fullscreen mode

Nesse projeto, teremos três pacotes: controller, model e o service. Segue a imagem abaixo:

Estrutura do projeto

Agora, vamos criar a classe EmailDetails dentro do pacote model. Essa classe será responsável pelas informações do e-mail como o destinatário, assunto, corpo da mensagem e anexo. Segue o código abaixo:

package com.henrique.Email.API.model;

public class EmailDetails {

    private String to;
    private String subject;
    private String body;
    private String attachment;

    public EmailDetails() {
    }

    public EmailDetails(String to, String subject, String body, String attachment) {
        this.to = to;
        this.subject = subject;
        this.body = body;
        this.attachment = attachment;
    }

    public String getTo() {
        return to;
    }

    public String getSubject() {
        return subject;
    }

    public String getBody() {
        return body;
    }

    public String getAttachment() {
        return attachment;
    }
}

Enter fullscreen mode Exit fullscreen mode

Agora, crie a interface EmailService dentro do pacote model. Essa interface terá dois métodos sendMail e sendMailWithAttachment. Segue o código abaixo:

package com.henrique.Email.API.model;

public interface EmailService {

    String sendMail(EmailDetails emailDetails);

    String sendMailWithAttachment(EmailDetails emailDetails) throws Exception;

}

Enter fullscreen mode Exit fullscreen mode

Bom, temos as configurações no applications.properties e já temos o pacote de model com os arquivos necessários. Vamos passar para o pacote de service.

Nesse pacote, vamos criar a classe EmailServiceImpl. Que terá a implementação dos métodos da interface EmailService. Aqui, teremos como dependência JavaMailSender, pois estamos utilizando o método send() para enviar o e-mail. Segue o código abaixo:

package com.henrique.Email.API.service;

import com.henrique.Email.API.model.EmailDetails;
import com.henrique.Email.API.model.EmailService;
import jakarta.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import java.io.File;

@Service
public class EmailServiceImpl implements EmailService {

    @Autowired
    private JavaMailSender javaMailSender;

    @Value("${spring.mail.username}")
    private String sender;

    @Override
    public String sendMail(EmailDetails emailDetails) {
        SimpleMailMessage message = new SimpleMailMessage();

        message.setFrom(sender);
        message.setTo(emailDetails.getTo());
        message.setSubject(emailDetails.getSubject());
        message.setText(emailDetails.getBody());

        javaMailSender.send(message);
        return "Mail Sent Successfully...";
    }

    @Override
    public String sendMailWithAttachment(EmailDetails emailDetails) throws Exception {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper;

        helper = new MimeMessageHelper(mimeMessage, true);

        helper.setFrom(sender);
        helper.setTo(emailDetails.getTo());
        helper.setSubject(emailDetails.getSubject());
        helper.setText(emailDetails.getBody());

        FileSystemResource file = new FileSystemResource(new File(emailDetails.getAttachment()));
        helper.addAttachment(file.getFilename(), file);

        javaMailSender.send(mimeMessage);
        return "Mail Sent Successfully...";
    }
}


Enter fullscreen mode Exit fullscreen mode

Feito isso, vamos passar para o pacote controller e nesse pacote, criaremos a classe EmailController, que terá os endpoints para que possamos testar o envio de e-mails. Segue o código abaixo:

package com.henrique.Email.API.controller;

import com.henrique.Email.API.model.EmailDetails;
import com.henrique.Email.API.model.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EmailController {

    @Autowired
    private EmailService emailService;

    @PostMapping("/sendMail")
    public ResponseEntity sendMail(@RequestBody EmailDetails details) {
       try {
           String result = emailService.sendMail(details);
           return ResponseEntity.ok(result);
       } catch (Exception ex) {
           return ResponseEntity.badRequest().body("Error while Sending Mail");
       }
    }

    @PostMapping("/sendMailWithAttachment")
    public ResponseEntity sendMailWithAttachment(@RequestBody EmailDetails details) {
        try {
            String result = emailService.sendMailWithAttachment(details);
            return ResponseEntity.ok(result);
        } catch (Exception ex) {
            return ResponseEntity.badRequest().body("Error while Sending Mail");
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

Agora, chegou a parte do teste. Vamos criar a classe EmailControllerTest no pacote de test do projeto. Nessa classe eu vou implementar o teste do endpoint /sendMailWithAttachment. Segue o código abaixo:

package com.henrique.Email.API.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.henrique.Email.API.model.EmailDetails;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import java.net.URI;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@AutoConfigureMockMvc
class EmailControllerTest {

    @Autowired
    private MockMvc mockMvc;

    ObjectMapper mapper = new ObjectMapper();

    @Test
    public void deveriaRetornarOEmailEnviado() throws Exception {
        EmailDetails details = new EmailDetails(
                "email@email.com",
                "Simple Email Message",
                "Hey! \n\nThis is a Simple Email with attachment\n\nThanks",
                "C:/caminho-da-imagem/nome.png"
        );

        URI uri = new URI("/sendMailWithAttachment");

        MvcResult mvcResult = mockMvc
                .perform(MockMvcRequestBuilders
                        .post(uri)
                        .content(mapper.writeValueAsString(details))
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers
                        .status()
                        .is(200)).andReturn();

        String expectedResponseBody = "Mail Sent Successfully...";
        String actualResponseBody = mvcResult.getResponse().getContentAsString();
        System.out.println(actualResponseBody);
        Assertions.assertEquals(expectedResponseBody, actualResponseBody);
    }
}
Enter fullscreen mode Exit fullscreen mode

Pronto. Se tudo ocorreu bem, a seguinte mensagem é exibida no console: Mail Sent Successfully...

E no Mailtrap aparecerá isso. Segue a imagem abaixo:

e-mail recebido no Mailtrap

Conclusão:
É isso! A ideia foi mostrar um exemplo simples de como utilizar a implementação do envio de e-mail do Spring Boot com o Mailtrap, com uma API Rest básica.

Até mais!

Link do repositório: https://github.com/Henrique2305/mail-api

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (1)

Collapse
 
gasper_lf profile image
Lewis Florez R.

tnanks

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay