sexta-feira, 5 de abril de 2013

Como enviar emails usando JavaMail

Neste post, vou apresentar como enviar um email através de uma servlet. 

Como de costume, criamos um projeto web dinâmico no eclipse, com, por exemplo, o nome "EnviarEmailServlet".

Para implementar este tutorial será necessária  a biblioteca JavaMail. A biblioteca pode ser encontrada no site da OracleNota: A menos que você esteja usando Java SE 6 ou mais recente, você também vai precisar da JavaBeans Activation Framework (JAF) que fornece o pacote javax.activation.

Depois de fazer o download, copie o arquivo mail.jar para a pasta lib do seu projeto.

O código-fonte da página index.jsp que contém o formulário para o envio do e-mail é:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Enviar E-Mail</title>
</head>
<body>

    <h1>Enviar E-Mail</h1>
    <form action="sendEmail.do" method="post">
        <table>
            <tr>
                <td>De</td>
                <td><input type="text" name="from" /></td>
            </tr>
            <tr>
            <tr>
                <td>Para</td>
                <td><input type="text" name="to" /></td>
            </tr>
            <tr>
                <td>Assunto</td>
                <td><input type="text" name="subject" /></td>
            </tr>
            <tr>
                <td>Mensagem</td>
                <td><textarea cols="25" rows="8" name="message"></textarea></td>
            </tr>
        </table>
        <br /> <input type="submit" value="Enviar" />
    </form>
</body>
</html>

Para receber estes parâmetros e enviar o e-mail devemos implementar uma servlet. Esta servlet vai se chamar SendEmail. Eu sobrescrevi o método init() da servlet para pegar os parâmetros necessários para o envio do email. A servlet deve conter o seguinte código:

package org.andvicoso.javamail.controller;

import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/sendEmail.do")
public class SendEmail extends HttpServlet {

    private static final String MSG_MIME_TYPE = "text/plain";

    private String host;
    private String port;
    private String login;
    private String password;

    @Override
    public void init() throws ServletException {
        ServletContext context = getServletContext();
        host = context.getInitParameter("host");
        port = context.getInitParameter("port");
        login = context.getInitParameter("login");
        password = context.getInitParameter("password");
    }

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        String resultMsg = "E-Mail enviado com sucesso!";
        String from = request.getParameter("from");
        String to = request.getParameter("to");
        String subject = request.getParameter("subject");
        String message = request.getParameter("message");

        try {
            Properties props = getSMTPProperties();

            Authenticator auth = new SMTPAuthenticator(login, password);

            Session session = Session.getInstance(props, auth);

            MimeMessage msg = createMessage(from, to, subject, message, session);

            Transport.send(msg);
        } catch (AuthenticationFailedException ex) {
            resultMsg = "Falha na autenticação";
        } catch (AddressException ex) {
            resultMsg = "E-Mail de destino inválido!";
        } catch (MessagingException ex) {
            resultMsg = ex.getMessage();
            //ex.printStackTrace();//descomentar para debug
        }

        request.setAttribute("message", resultMsg);

        RequestDispatcher dispatcher = request
                .getRequestDispatcher("result.jsp");
        dispatcher.forward(request, response);
    }

    private MimeMessage createMessage(String from, String to, String subject,
            String message, Session session) throws MessagingException {
        MimeMessage msg = new MimeMessage(session);
        msg.setText(message);
        msg.setSubject(subject);
        msg.setFrom(new InternetAddress(from));
        msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
        msg.setContent(message, MSG_MIME_TYPE);
        msg.setSentDate(new Date());

        return msg;
    }

    private Properties getSMTPProperties() {
        Properties props = new Properties();
        props.setProperty("mail.host", host);
        props.setProperty("mail.transport.protocol", "smtp");
        // Comente essas 4 linhas abaixo se deseja usar o SSL
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.smtp.port", port);
        props.setProperty("mail.smtp.ssl.trust", host);
        props.setProperty("mail.smtp.starttls.enable", "true");
        // Descomente essas tres linhas abaixo se deseja usar SSL
//         props.setProperty("mail.smtps.auth", "true");
//         props.setProperty("mail.smtps.port", port);
//         props.setProperty("mail.smtps.ssl.trust", host);
        //Descomente a linha abaixo se deseja informações de debug
//        props.put("mail.debug", "true");

        return props;
    }

    private class SMTPAuthenticator extends Authenticator {
        private String login;
        private String password;

        public SMTPAuthenticator(String login, String password) {
            this.login = login;
            this.password = password;
        }

        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(login, password);
        }
    }
}

Se você preferir para criptografar suas conexões com SSL, então certifique-se de suas propriedades incluam SMTPS em vez de SMTP e que a propriedade mail.smtps.ssl.trust seja definida.

Para enviar e-mail para vários destinatários apenas adicionar mais endereços através do método  addRecipient.

Para anexar um ou mais arquivos no e-mail devemos alterar o tipo do conteúdo do e-mail para MimeMultipart na função createMessage.

Segue o código para isso:

    // cria uma parte do corpo da mensagem como sendo o texto
    MimeBodyPart messageBodyPart = new MimeBodyPart();
    // preenche a mensagem do e-mail
    messageBodyPart.setText(message);

    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(messageBodyPart);

    // a segunda parte do corpo é o anexo
    messageBodyPart = new MimeBodyPart();
    DataSource source = new FileDataSource(fileAttachment);//esse fileAttachment é caminho para o arquivo!
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(fileAttachment);
    multipart.addBodyPart(messageBodyPart);

    // seta o conteúdo da mensagem como sendo o multipart criado (texto+arquivo)
    msg.setContent(multipart);//ao invés de msg.setContent(message, MSG_MIME_TYPE);

Uma outra ideia interessante é usar um arquivo properties para armazenar as propriedades do servidor SMTP.

Para armazenar os parâmetros necessários para a conexão com o servidor SMTP eu adicionei parâmetros de contexto no web.xml. Desta maneira:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>JavaMail</display-name>

    <!-- SMTP settings -->
    <context-param>
        <param-name>host</param-name>
        <param-value>smtp.gmail.com</param-value>
        <!-- ou outro se não for gmail -->
    </context-param>

    <context-param>
        <param-name>port</param-name>
        <param-value>587</param-value>
        <!-- O padrão é 25. Podemos usar a 26 se o ISP bloquear a 25 -->
    </context-param>

    <context-param>
        <param-name>login</param-name>
        <param-value>abc@gmail.com</param-value>
        <!-- ou outro email se não for gmail -->
    </context-param>

    <context-param>
        <param-name>password</param-name>
        <param-value>abc</param-value>
        <!-- colocar a senha do email -->
    </context-param>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Altere os valores parâmetros no web.xml para os seus valores e depois é só testar!

Para este exemplo também é possível encontrar um projeto exemplo no meu dropbox.

Até o próximo post!

[]`s

0 comentários:

Postar um comentário

Popular Posts

StackOverflow Profile


profile for andvicoso at Stack Overflow, Q&A for professional and enthusiast programmers