Criando uma API com Spring Boot para o envio de e-mail
Tags: java, springboot, mailtrap
Published: 2024-03-29 02:37:21

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7r6b6xbeh6c46m6bnppn.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g07vvadqvyojsg2d1mqc.png)

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
```

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


![Estrutura do projeto](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9tr8vyttffhixz9yn94.png)

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;
    }
}

```

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;

}

```

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...";
    }
}


```

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");
        }
    }
}


```

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);
    }
}
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/crb89s7ihtmcvz55a080.png)



**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