Spring Framework 3 Configurando o Serviço JavaMail

No artigo anterior, Spring 3 – 100% Livre de XML, foi demonstrado um exemplo de configuração dos beans do Spring sem a necessidade do uso de arquivos de configuração por XML. Desta vez, seguindo a mesma linha, será abordada a configuração do serviço de email fornecido pelo Spring através da biblioteca JavaMail. Vamos trabalhar com envio de mensagem no formato HTML, com lista de anexos e também veremos como inserir uma imagem no corpo da mensagem.

1. Preparando o projeto

Para o exemplo deste tutorial será necessário o uso das seguintes bibliotecas:

2. Iniciando o projeto

Crie um projeto na sua IDE de preferência e adicione as bibliotecas citadas. Feito isso, vamos criar a classe MyMessage, a qual terá alguns atributos e métodos que irão armazenar as informações dos emails que serão enviados. Alguns destes atributos são: o corpo da mensagem, lista de anexos, assunto da mensagem, lista de destinatários, entre outras.

Listagem 1. Classe MyMessage.
package com.wp.mb.tutorial.entity;

import java.util.ArrayList;
import java.util.List;

/**
 * https://www.mballem.com
 */
public class MyMessage {

    private String from;
    private String personal;
    private String text;
    private String subject;
    private List attachments = new ArrayList();
    private String[] users;
    private String[] fileBody = new String[2];

    //gere os métodos get/set

    //adiciona uma imagem no corpo da mensagem
    public void addFileBody(String cid, String file) {
        this.fileBody[0] = cid;
        this.fileBody[1] = file;
    }

    //adicionar os anexos da mensagem
    public void addAttachment(String... files) {
        for (String file : files) {
            this.attachments.add(file);
        }
    }

    //adicionar os destinatarios da mensagem
    public void addUser(String... toUsers) {
        this.users = toUsers;
    }
}

Em seguida vamos adicionar a classe JavaMailService, a qual será responsavel pelo envio e por adicionar no objeto de envio os dados que formam a mensagem de email a ser enviada. Esta classe será também um bean gerenciado pelo Spring, o qual será configurado na classe BeanJavaMailSource da Listagem 3.

Listagem 2. Classe JavaMailService.
package com.wp.mb.tutorial.service;

import com.wp.mb.tutorial.entity.MyMessage;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * https://www.mballem.com
 */
public class JavaMailService {
    //objeto responsavel por enviar a mensagem.
    private JavaMailSender javaMailSender;

    public JavaMailService(JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
    }

    public void sendMail(MyMessage message) {
        //objeto que recebe os dados a serem enviados na mensagem.
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        //quando trabalhamos com anexos, devemos usar um objeto
        // do tipo MimeMessageHelper.
        MimeMessageHelper helper;

        try {
            //inicializamos o obejto helper.
            helper = new MimeMessageHelper(mimeMessage, true);
            //inserimos dados de quem está enviando a mensagem.
            helper.setFrom(message.getFrom(), message.getPersonal());
            //inserimos os destinatarios
            helper.setTo(message.getUsers());
            //inserimos a data de envio
            helper.setSentDate(new Date());
            //inserimos o texto da mensagem,
            // o atributo true indica que será em html.
            helper.setText(message.getText(), true);
            //inserimos o assunto da mensagem.
            helper.setSubject(message.getSubject());
            //inserimos uma imagem no corpo da mensagem.
            //o 1° parametro será o cid, id do anexo que será inserido.
            //o 2° parametro será a url onde o arquivo está armazenado em disco.
            helper.addInline(
                    message.getFileBody()[0],
                    new FileSystemResource(message.getFileBody()[1])
            );
            //inserimos os anexos adicionados a lista de anexos.
            // Fazemos um for() na lista para adicionar um anexo por vez.
            for (String anexo : message.getAttachments()) {
                File attach = new File(anexo);
                helper.addAttachment("Attachment: " + attach.getName(), attach);
            }
            //objeto de envio da mensagem.
            javaMailSender.send(mimeMessage);
            System.out.println("Envio com Sucesso!");
        } catch (MailException e) {
            System.out.println("Email não pode ser eviado!\n" + e.getMessage());
        } catch (MessagingException e) {
            System.out.println("Email não pode ser eviado.\n" + e.getMessage());
        } catch (IOException e) {
            System.out.println("Anexo não encontrado\n" + e.getMessage());
        }
    }
}

Agora vamos configurar o bean do Spring responsável por gerenciar o objeto de envio, o JavaMailSenderImpl. As configurações necessárias para a conexão com servidor de email serão adicionadas a um arquivo de propriedades, o qual será lido pelo Spring através do bean mailProperties e adicionadas as variáveis de instancia configuradas com as anotações @Value. O JavaMail trabalha com algumas configurações de propriedades, que neste caso serão inseridas no método mailProps() e posteriormente adicionadas as configurações do bean javaMailSender. No bean javaMailService, adicionamos no parmetro do construtor da classe JavaMailService, um objeto inicializado referente ao bean javaMailSender.

Listagem 3. Classe BeanJavaMailSource.
package com.wp.mb.tutorial.configuration;

import com.wp.mb.tutorial.service.JavaMailService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderSupport;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

/**
 * https://www.mballem.com
 */
@Configuration
public class BeanJavaMailSource {

    @Value("#{props['mail.host']}")
    private String host;
    @Value("#{props['mail.port']}")
    private int port;
    @Value("#{props['mail.protocol']}")
    private String protocol;
    @Value("#{props['mail.encoding']}")
    private String encoding;
    @Value("#{props['mail.smtp.starttls.enable']}")
    private String starttls;
    @Value("#{props['mail.user']}")
    private String user;
    @Value("#{props['mail.pass']}")
    private String pass;

    @Bean(name = "javaMailSender")
    public JavaMailSender javaMailSender() {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost(host);
        mailSender.setPort(port);
        mailSender.setProtocol(protocol);
        mailSender.setUsername(user);
        mailSender.setPassword(pass);
        mailSender.setDefaultEncoding(encoding);
        mailSender.setJavaMailProperties(mailProps());
        return mailSender;
    }

    @Bean(name = "javaMailService")
    public JavaMailService javaMailService() {
        return new JavaMailService(javaMailSender());
    }

    @Bean(name = "props")
    public PropertiesLoaderSupport mailProperties() {
        PropertiesFactoryBean props = new PropertiesFactoryBean();
        props.setLocation(new ClassPathResource("/mail.properties"));
        return props;
    }

    private Properties mailProps() {
        Properties properties = new Properties();
        properties.setProperty("mail.smtp.starttls.enable", starttls);
        return properties;
    }
}

O arquivo de propriedades, mail.properties, deve ser adicionado dentro do diretório “src” do projeto, veja a seguir os dados que compõem o arquivo:

mail.host = smtp.gmail.com
mail.port = 587
mail.protocol = smtp
mail.encoding = ISO-8859-1
mail.smtp.starttls.enable = true
mail.user = marcio@gmail.com
mail.pass = minha_senha123
Listagem 4. Classe Teste.
package com.wp.mb.tutorial;

import com.wp.mb.tutorial.entity.MyMessage;
import com.wp.mb.tutorial.service.JavaMailService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.io.Resource;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * https://www.mballem.com
 */
public class Teste {

    private JavaMailService mailService;
    private AnnotationConfigApplicationContext ctx;

    public Teste(JavaMailService mailService,
                 AnnotationConfigApplicationContext ctx)
    {
        this.mailService = mailService;
        this.ctx = ctx;
    }

    public static void main(String[] args) {
        //inicializa o container do Spring.
        AnnotationConfigApplicationContext ctx =
                new AnnotationConfigApplicationContext();

        //informa ao Spring onde ele deve procurar por classes anotadas
        ctx.scan("com.wp.mb.tutorial");
        ctx.refresh();

        Teste t = new Teste(ctx.getBean(JavaMailService.class), ctx);

        t.sendMail();
    }

    //método onde serão informados os dados de envio.
    private void sendMail() {
        //podemos adicionar varios destinatarios.
        String to1 = "marcos@gmail.com";
        String to2 = "joana@hotmail.com";
        String to3 = "maria@bol.com.br";

        //objeto para inserir os dados de envio
        MyMessage message = new MyMessage();
        //informamos o assunto da mensagem
        message.setSubject("Teste Spring Mail");
        //inserimos o corpo da mensagem,
        // neste caso um string com o html do arquivo mensagem.html
        message.setText(readFile());
        //inserimos os destinatarios
        message.addUser(to1, to2, to3);
        //inserimos a imagem do corpo da mensagem
        message.addFileBody("0001", "C:\\spring.png");
        //inserimos 2 anexos
        message.addAttachment("C:\\logo-mongodb.png", "C:\\duke.jpg");
        //inserimos os dados do rementente que
        // serão exibidos na mensagem
        message.setFrom("marcio@gmail.com");
        message.setPersonal("mballem.wordpress.com");
        //chama o método de envio da classe JavaMailService.
        mailService.sendMail(message);
    }

    //método responsavel por ler o arquivo html.
    private String readFile() {
        Resource resource = ctx.getResource("classpath:/mensagem.html");
        String html = "";
        try {
            BufferedReader bufferedReader =
                    new BufferedReader(new FileReader(resource.getFile()));
            String linha = "";
            while ((linha = bufferedReader.readLine()) != null) {
                html = html + linha;
            }
            bufferedReader.close();
            return html;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Veja a seguir o conteúdo do arquivo mensagem.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
    Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/html">
<head>
    <meta content="text/html" http-equiv="content-type">
    <title>JavaMail com Spring Framework</title>
</head>
    <body>
        <div id="_div">
            <img src='cid:0001'><br>
            <b>JavaMail With Spring Framework</b><br>
            Trabalhando com JavaMail em conjunto com o Spring
            Framework 3 sem o uso de configuração por XML.<br>

            * download
            <a href="http://www.oracle.com/technetwork/java/javamail/index.html">
                JavaMail
            </a> library.<br>

            * download
            <a href="http://www.springsource.org/download/community">
                Spring Framework
            </a> library.<br>
        </div>
    </body>
</html>

Crie esse arquivo no diretório src do seu projeto. Note que na tag  adicionamos como atributo o códido cid:0001. é através deste código que podemos inserir uma imagem no corpo do email. Cada imagem inserida no corpo do email deverá possuir um código único.

Veja na Figura 1, a estrutura do projeto:

Figura 1 – Estrutura do projeto.

Confira na Figura 2 um exemplo de como o email enviado será recebido pelo destinatário. Veja que temos 3 imagens, onde 2 são enviadas como anexo e uma delas está adicionada ao corpo da mensagem de email, logo acima do texto da mensagem. Temos também o assunto do email: “Teste Spring Mail”, e logo abaixo do assunto, é possível visualizar os dados do remetente: “mballem.wordpress.com marcio@gmail.com”.

Figura 2 – Exemplo do e-mail recebido.

Saiba mais em:

Até 2013!

Ballem

Marcio Ballem é bacharel em Sistemas de Informação pelo Centro Universitário Franciscano em Santa Maria/RS. Tem experiência com desenvolvimento Delphi e Java em projetos para gestão pública e acadêmica. Possui certificação em Java, OCJP 6.

Você pode gostar...