miércoles, 12 de junio de 2013

JAVA: Envío de mail con GMail desde Tomcat

Antes de nada, me gustaría pedir disculpas por lo exageradamente lento que me he vuelto publicando post en el blog. Esto se debe a que tengo una serie de temas entre manos que me están absorbiendo casi todo mi tiempo. Espero poder estar a full con vosotros dentro de poco.

Introducción

 Muchas veces necesitamos que nuestra aplicación web envié emails a usuarios o incluso a nosotros mismos. En este post hablaremos de cómo implementar con estas notificaciones haciendo uso de un correo de GMail y Tomcat.

Descargándonos las librerías

Para poder trabajar vamos a necesitar dos librerías de Java que descargaremos de la web de Oracle:

Una vez descargadas deberemos colocarlas en el directorio lib de Tomcat 7.x (no nos vale meterlas directamente en nuestro proyecto).



Una vez tengamos esto, ya podemos crear el proyecto web desde NetBeans.

Creando la aplicación web

Crearemos un proyecto web que llamaremos DemoWSaMail para desplegar en Tomcat tal y como ya hemos aprendido en post anteriores. No tiene misterio: Apache Tomcat: Instalación y despliegue de WebServices con NetBeans.

Una vez creado, añadiremos las referencias a nuestras nuevas librerías que hemos instalado en Tomcat.



Creando el WS que envía el mail

 Crearemos un web service que llamaremos EnviaMailWS en el paquete com.demo.demowsamail.webservices, recordando añadir la configuración METRO cuando nos pregunte:



A esta función le añadiremos un método web enviarMail que recibirá tres parámetros: destino, asunto y mensaje.

    @WebMethod(operationName = "enviarMail")
    public String enviarMail(@WebParam(name = "destino") String destino,
                             @WebParam(name = "asunto") String asunto,
                             @WebParam(name = "mensaje") String mensaje) {
        (...)
    }

Como es evidente, para conectarnos al servidor de GMail necesitaremos definir en el método dos propiedades donde indicar usuario y clave:

    final String username = "usuario.de.gmail@gmail.com";
    final String password = "clave.de.gmail";

Después, indicaremos las propiedades de GMail que necesitaremos para crear la sesión:

    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.port", "465");

Inicializamos la sesión usando como autenticación los datos que hemos definido previamente:

    Session session = Session.getInstance(props,
      new javax.mail.Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
            }
      });

Y finalmente, creamos y enviamos el mensaje:

    try {
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(username));
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(destino));
        message.setSubject(asunto);
        message.setText(mensaje);

        Transport.send(message);

    } catch (MessagingException e) {
            result = "ERROR! " + e.getMessage();
    }

En resumen, nuestra clase quedará así:

package com.demo.demowsamail.webservices;

import java.util.Properties;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;

//imports para el correo
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
//fin de los imports para el correo

/**
 *
 * @author jose.c.arcenegui
 */
@WebService(serviceName = "EnviaMailWS")
public class EnviaMailWS {
   
    @WebMethod(operationName = "enviarMail")
    public String enviarMail(@WebParam(name = "destino") String destino,
                             @WebParam(name = "asunto") String asunto,
                             @WebParam(name = "mensaje") String mensaje) {
   
        String result="email enviado!";
       
        final String username = "notifications.ayudamehc@gmail.com";
        final String password = "founders.ayudamehc";

        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "465");
       
        Session session = Session.getInstance(props,
          new javax.mail.Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                }
          });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(username));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(destino));
            message.setSubject(asunto);
            message.setText(mensaje);

            Transport.send(message);

        } catch (MessagingException e) {
                result = "ERROR! " + e.getMessage();
        }
       
        return result;
    }
}

Y al probar nuestro mensaje, veremos cómo nos llega un  mail:





Y con esto y un bizcocho, os dejo el código en el dropbox.


MUY IMPORTANTE: Cuando vayáis a desplegar esto en un servidor que no sea vuestro local, aseguraos que tiene las librerías activation.jar y mail.jar en vuestro servidor de destino.