Enviando Email com Java - Usando Spring e Velocity e o SMTP do Gmail

Neste post não irei demonstrar a aplicação completa, mas apenas os arquivos que você precisa alterar e/ou adicionar em sua aplicação para enviar email, usando o Spring e o Velocity, pressuponho que sua aplicação já esteja utilizando o Spring. Como forma de exemplo e para você fazer sua aplicação funcionar sem precisar por enquanto de um servidor SMTP, usaremos o do Gmail.
O velocity é um projeto template-engine da Apache Software Foundation para aplicações Web. Ele permite que você crie templates de texto, html, xml ou o que preferir e deixe-o separado do seu código Java, podendo interagir com ele. Permite por exemplo que o designer trabalhe em paralelo com os programadores, enquanto fazem o html os programadores fazem o código Java.
Neste exemplo iremos usar o velocity para criar templates de email, textos padrões que serão criados e que receberão parâmetros do seu código Java, isto pode ser bem útil.


O velocity possui a velocity language, e com ela você interagir com o texto criado. Você pode trabalhar não apenas com String, mas também com o próprio objeto, além de pode usar vários métodos como if, else if, foreach, entre outros.
Para baixar os jars do velocity acesse a página oficial da Apache http://velocity.apache.org/, lá você também encontra toda a documentação.
Após baixar os jars, coloque-os no seu projeto na pasta WebContent/WEB-INF/lib e no classpath da sua aplicação.
No seu arquivo applicationContext.xml adicione as seguintes linhas:

<!-- Configurações do VelocityEngine -->
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
      <property name="velocityProperties">
         <value>
            resource.loader=file
            file.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
         </value>
      </property>
</bean>
<!-- Propriedades do JavaMailSender com SMTP do Gmail -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.gmail.com" />
    <property name="port" value="465" />
    <property name="protocol" value="smtps" />
    <property name="username" value="seu_email@gmail.com"/>
    <property name="password" value="sua_senha"/>
    <property name="javaMailProperties">
            <props>
            <prop key="mail.smtps.auth">true</prop>
            <prop key="mail.smtps.starttls.enable">true</prop>
            <prop key="mail.smtps.debug">true</prop>
            </props>
      </property>
     </bean>
Segue abaixo minha classe de Envio de Email EmailServico.java:

//imports
@Service("emailServico")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor=Throwable.class)
public class EmailServico {
@Autowired
private JavaMailSender mailSender;
@Autowired
private VelocityEngine velocityEngine;
private static final String TEMPLATE = "templates/velocity/email.vm";
private static final String FROM = comunicacao@gmail.com;
private static final String SUBJECT = "Emissão de Portaria - SEDUC";
public void enviarEmail(final Pessoa pessoa){
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
message.setTo(pessoa.getEmail());
message.setFrom(FROM);
message.setSubject(SUBJECT);
                                //passando os parâmetros para o template
Map<String, Object> model = new HashMap<String, Object>();
model.put("pessoa",pessoa);
String text = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, TEMPLATE, model);
message.setText(text,true);
}
};
this.mailSender.send(preparator);
}
//getters e setters
}
O template de exemplo que vou mostrar já utilizará o if. A sintaxe para utilizar seus objetos no texto é $ (cifrão) seguido do nome do parâmetro que você passou, por exemplo $pessoa

Para utilizar o condicional if a sintaxe é: 
#if(condição) O texto caso entre no if. #end

Caso queira verificar se um objeto tem valor null você não pode utilizar assim:
#if(objeto==null) O texto caso entre no if. #end

Não é possível fazer comparações desta forma, se quiser fazer comparação com null utilize assim:
#if(objeto) O objeto retorna verdadeiro se não for null. #else O objeto retorna falso caso seja null. #end

Uma ótima referência para se saber o que você pode usar com VL se encontra aqui: http://velocity.apache.org/engine/releases/velocity-1.5/user-guide.html.

Segue meu template de exemplo, o padrão para nomearmos é nome.vm. Segue o meu arquivo email.vm que coloquei em resouces.templates.velocity:
## Esta é a forma de usar comentários no VL (Velocity Language)

Olá $pessoa.Nome! Seu email foi cadastrado com sucesso. Seguem seus dados:
Email: $pessoa.Email
## Estou verificando se o CPF é diferente de null para mostrar os dados
#if($pessoa.Cpf) CPF: $pessoa.Cpf #end
#if($pessoa.Idade>=18) Maior de Idade #else Menor de Idade #end
O resultado será algo como:

Olá Frederico Maia! Seu email foi cadastrado com sucesso. Seguem seus dados:
Email: fredericomaia10@gmail.com
CPF: 111.111.111-11
Maior de Idade 
Pra utilizar sua classe de email agora é só fazer algo como:

//imports
@Service("notificacaoFachada")
public class NotificacaoFachada {
@Autowired
private EmailServico emailServico;
public void enviarEmail(Pessoa pessoa) throws FachadaException{
try{
emailServico.enviarEmail(pessoa);
} catch (Exception e) {
throw new FachadaException(e);
}
}
}
A classe Pessoa algo como:

//imports
public class Pessoa{

private String nome;
       private String email;
        private String cpf;
        private String idade;
       //getters e setters
}

Caso eu tenha esquecido algo ou você tenha dúvidas em algo, é só comentar.



Frederico Maia Arantes
Analista e Desenvolvedor de Sistemas Java EE
Oracle Certified Professional, Java SE 6 Programmer 
Twitter

Comentários

Postagens mais visitadas deste blog

Gerando Documentos Word .docx com Java

Empregos Java - Divulgados pelo DFJUG