[Métodos] Java Mail - Parte IV - Recibir un Mail




Para poder leer correos de nuestro mail como cualquier servicio de web mail pero en hecho en java vamos a necesitar importar la dependencia de Java Mail, crear un conjunto de propiedades, crear la sesion, y ahora contamos con los objetos Store y Folder, ademas de la clase Message para cada email.


  1. Crear un conjunto de propiedades, a las cuales hay que setearle las propiedades:
    Properties prop = new Properties();

    • Deshabilitar el TLS (Transport Layer Security)
      • prop.setProperty("mail.pop3.starttls.enable", "false");

    • Avtivar en su lugar SSL (Secure Sockets Layer)
      • prop.setProperty("mail.pop3.socketFactory.class","javax.net.ssl.SSLSocketFactory" );
        prop.setProperty("mail.pop3.socketFactory.fallback", "false");

    • Le indicamos el puerto de conexion (995)
      • prop.setProperty("mail.pop3.port","995");
        prop.setProperty("mail.pop3.socketFactory.port", "995");

  2. Creamos una sesion, con las properties recién definidas:
    • Session sesion = Session.getInstance(prop);

  3. Pasamos a crear los objetos, Store y Folder. Store vendria a ser como la cuenta de mail que guarda los diversos correos, Folder la carpeta donde se guardan estos(EJ: recibidos, enviados, spam, etc)
    • Store store;
      Folder folder;

  4. Inicializamos estos objetos dentro de un try-catch, pidiéndole a la Session que obtenga el 'almacen' y lo conecte, pasando el host, usuario y contraseña.
    Luego a este 'almacen' le pedimos que obtenga la carpeta y la abra con una propiedad de READ_ONLY para no marcar los correos como leido. Caso contrario usamos READ_WRITE:
    • store= sesion.getStore("pop3");
      store.connect("pop.gmail.com","nuestro_mail@gmail.com","nuestra_contraseña");
      folder= store.getFolder("[Gmail]/Send");
      folder.open(Folder.READ_ONLY);

  5. Creamos nnuestro objeto Message que representa el correo electronico en si mismo como un array de mensajes.
    • Message [] mensajes= folder.getMessages();

  6. Ya tendremos nuestro array de mensajes para mostrar, imprimiendo simplemente en pantalla, podemos utlizar un ciclo for para leer cada uno
    • for (int i = 0; i < mensajes.length; i++){     System.out.println("DE : " + mensajes[i].getFrom()[0].toString());
          System.out.println("ASUNTO: " + mensajes[i].getSubject());
      }


El resultado puede variar, dependiendo de los correos recibidos. Mi resultado fu este:



Mi método completo es el siguiente.
public void leerCorreo(){
    Properties prop = new Properties();

    // Deshabilitamos TLS
    prop.setProperty("mail.pop3.starttls.enable", "false");

    // Hay que usar SSL
    prop.setProperty("mail.pop3.socketFactory.class","javax.net.ssl.SSLSocketFactory" );
    prop.setProperty("mail.pop3.socketFactory.fallback", "false");

    // Puerto 995 para conectarse.
    prop.setProperty("mail.pop3.port","995");
    prop.setProperty("mail.pop3.socketFactory.port", "995");

    Session sesion = Session.getInstance(prop);
    sesion.setDebug(false);

    Store store;
    Folder folder;
    try {
        store = sesion.getStore("pop3");
        store.connect("pop.gmail.com","dar10comyr@gmail.com","blogspot2016");

        folder = store.getFolder("INBOX");
        folder.open(Folder.READ_ONLY);

        Message [] mensajes = folder.getMessages();

        for (int i = 0 ; i < mensajes.length; i++){
            System.out.println("DE    : " + mensajes[i].getFrom()[0].toString());
            System.out.println("ASUNTO: " + mensajes[i].getSubject());
        }
    } catch (NoSuchProviderException e){
        e.printStackTrace();
    } catch (MessagingException e) {
        e.printStackTrace();
    }
}




OBTENER TODAS LAS CARPETAS


Para obtener mas carpetas ademas de la de 'INBOX', deberemos cambiar el protocolo de conexion de POP a IMAP
  1. Creamos nuestras propiedades.
  2. Le seteamos un única propiedad:
    • prop.setProperty("mail.store.protocol", "imaps");
  3. Creamos una sesion con las properties creadas.

  4. Obtenemos un Store pidiendoselo a la sesion pero esta vez con el protocolo IMAP
    • Store store= sesion.getStore("imaps");

  5. Le pedimos al Store que se conecte pasandole el host pero como protocolo POP, el usuario y la contraseña (igual que antes).

  6. Ahora, vamos a obtener un array de del Folders para luego recorrerlo y obtener de si mismo el nombre de la carpeta (o todos)
    • Folder[] folders= store.getDefaultFolder().list("*")

  7. Realizamos una pequeña comprobación con un if, ya que vamos a pedirle al Folder que nos obtenga el 'tipo', que es un número y solo nos interesa que sea el '3' (Ya que tambien existe un tipo '2' que no contiene 'folders' válidos).
    • if (folder.getType() == 3) {     System.out.println(folder.getFullName() + ": " + folder.getMessageCount());

  8. Ahora obtenemos el folder, pidiendosele al Store pero esta vez le pasamos como parametro, el mismo 'folder' que obtiene su nombre.
    • folder = store.getFolder(folder.getFullName());

  9. Nuevamente le seteamos la opcion de 'READ ONLY' para que no los marque como leidos, si es que lo queremos asi:
    • folder.open(Folder.READ_ONLY);

  10. Volvemos a crear nuestro array de mensajes que luego iteraremos para leer cada mensaje de cada carpeta:
    • Message [] mensajes= folder.getMessages();

  11. Por ultimo el mismo for para ver aunque sea por pantalla los resultados:
    • for (int i = 0; i < mensajes.length; i++){     System.out.println("DE : " + mensajes[i].getFrom()[0].toString());
          System.out.println("ASUNTO: " + mensajes[i].getSubject());
      }

Mi resultado fue mas o menos asi:





El codigo completo de esta clase es:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public void LeerCorreos() {
    Properties props = System.getProperties();
    props.setProperty("mail.store.protocol", "imaps");
    try {
        Session session = Session.getDefaultInstance(props, null);
        Store store = session.getStore("imaps");
        store.connect("imap.gmail.com", "dar10comyr@gmail.com", "blogspot2016");
        Folder[] folders = store.getDefaultFolder().list("*");
        for (Folder folder : folders) {
            if (folder.getType() == 3) {
                System.out.println(folder.getFullName() + ": " + folder.getMessageCount());

                folder = store.getFolder(folder.getFullName());
                folder.open(Folder.READ_ONLY);

                Message [] mensajes = folder.getMessages();

                for (int i = 0 ; i < mensajes.length; i++){
                    System.out.println("DE    : " + mensajes[i].getFrom()[0].toString());
                    System.out.println("ASUNTO: " + mensajes[i].getSubject());
                }
            }
        }
    } catch (MessagingException e) {
        e.printStackTrace();
    }
}


Comparte esto:



[Métodos] Java Mail - Parte III - Enviar mail adjuntando archivos


Para poder recrear desde nuestro codigo Java, el envio de un mail con la opcion de adjuntar archivos,

Debemos hacer los mismos pasos que el envio de un mail sencillo ,

Con la pequeña particularidad que al objeto MimeMessage no le setearemos un String (con el contenido del mensaje) sino en su lugar un objeto MimeMultipart, a las cuales habrá que agregarles otros objetos MimeBodyPart que representan el texto (contenido del mensaje) por un lado y el archivo adjunto por otro.

El procedimiento es idéntico al envio de un mail normal hasta setearle al MimeMessage el mensaje, en lugar de usar el metodo setText(String) usaremos este otro setContent(MultiPart)
El codigo queria basicamente igual

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// (1)Crear una sesión de mail, seteando algunas propiedades
Properties misPropiedades = new Properties();
misPropiedades.setProperty("mail.smtp.host", "smtp.gmail.com");
misPropiedades.setProperty("mail.smtp.starttls.enable", "true");
misPropiedades.setProperty("mail.smtp.port", "587");
misPropiedades.setProperty("mail.smtp.user", "dar10comyr@gmail.com");
misPropiedades.setProperty("mail.smtp.auth", "true");

Session session = Session.getDefaultInstance(misPropiedades);

// (2)Construir objeto MimeMessage, con el objeto session.
MimeMessage message = new MimeMessage(session);

// (3)Al mensaje le seteamos emisor, destinatario, CC, Asunto, Mensaje.
try {
    message.setFrom(new InternetAddress("dar10comyr@gmail.com"));
    message.addRecipient(Message.RecipientType.TO, new InternetAddress("Destinatario@ejemplo.com"));
    message.addRecipient(Message.RecipientType.CC, new InternetAddress("CarbonCopy@ejemplo.com"));
    message.addRecipient(Message.RecipientType.BCC, new InternetAddress("BlindCarbonCopy@ejemplo.com"));
    message.setSubject("Hola");
    //message.setText("Correo enviado con Java Mail =)");

 /* ***AQUI IMPLEMENTAMOS MIMEBODYPART*** */

} catch (AddressException e) {
    e.printStackTrace();
} catch (MessagingException e) {
    e.printStackTrace();
}
// (4)Creamos un objeto 'Transport', y ejecutamos la emision del correo a través de sus metodos.
try {
    Transport t = session.getTransport("smtp");
    t.connect("dar10comyr@gmail.com", "lacontraseñadelmail");
    t.sendMessage(message, message.getAllRecipients());
    t.close();
} catch (NoSuchProviderException e) {
    e.printStackTrace();
} catch (MessagingException e) {
    e.printStackTrace();
}

Adjuntando archivos

Necesitaremos crear:
  • Un objeto de MimeMultipart a el cual hay que agregarles los objetos del cuerpo del mensaje y el/los archivos adjuntados.
  • Objetos de MimeBodyPart
    • Uno para el cuerpo del mensaje
    • Los que sean necesarios para adjuntar archivos.

Primero el mensaje:

MimeBodyPart mensaje = new MimeBodyPart();
mensaje.setText("Buenos dias a ti!\nTe envio este mail con JavaMail y te adjunto el codigo\nSalu2");

En segundo lugar podemos enviar un archivo de la extension que sea, (imagino que con un limite de peso, aunque lo desconosco)

MimeBodyPart archivoAdjunto = new MimeBodyPart();
FileDataSource fuenteArchivosDatos = new FileDataSource("C:\\mail.java");
DataHandler manejadorDatos = new DataHandler(fuenteArchivosDatos);
archivoAdjunto.setDataHandler(manejadorDatos);

Ahora si juntamos ambas parte y se las agregamos a MimeMultiPart

MimeMultipart multiParte = new MimeMultipart();
multiParte.addBodyPart(mensaje);
multiParte.addBodyPart(archivoAdjunto);

el resultado ha sido:




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.dar10comyr.blogspot;

import java.util.*;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;

public class Imail {
    public static void main(String...Dar10){
  //Crear una sesión de mail, seteando algunas propiedades
    Properties misPropiedades = new Properties();
    misPropiedades.setProperty("mail.smtp.host", "smtp.gmail.com");
    misPropiedades.setProperty("mail.smtp.starttls.enable", "true");
    misPropiedades.setProperty("mail.smtp.port", "587");
    misPropiedades.setProperty("mail.smtp.user", "dar10comyr@gmail.com");
    misPropiedades.setProperty("mail.smtp.auth", "true");

    Session session = Session.getDefaultInstance(misPropiedades);
    session.setDebug(true);

    //Construir objeto MimeMessage, con el objeto session.
    MimeMessage message = new MimeMessage(session);

    //Al mensaje le seteamos emisor, destinatario, CC, Asunto, Mensaje.
    try {
        message.setFrom(new InternetAddress("dar10comyr@gmail.com"));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress("destinatario@example.com"));
        message.addRecipient(Message.RecipientType.CC, new InternetAddress("CarbonCopy@example.com"));
        message.addRecipient(Message.RecipientType.BCC, new InternetAddress("BlindCarbonCopy@ejemplo.com"));
        message.setSubject("Mail adjuntando archivo");
        
        /* ***AQUI IMPLEMENTAMOS MIMEBODYPART*** */
        
        MimeBodyPart mensaje = new MimeBodyPart();
        mensaje.setText("Buenos dias a ti!\nTe envio este mail con JavaMail y te adjunto el codigo\nSalu2");
        //===============================================\\
        MimeBodyPart archivoAdjunto = new MimeBodyPart();
        FileDataSource fuenteArchivosDatos = new FileDataSource("ruta del archivo");
        DataHandler manejadorDatos = new DataHandler(fuenteArchivosDatos);
        archivoAdjunto.setDataHandler(manejadorDatos);
      //===============================================\\
        MimeMultipart multiParte = new MimeMultipart();
        multiParte.addBodyPart(mensaje);
        multiParte.addBodyPart(archivoAdjunto);
      //===============================================\\
        message.setContent(multiParte);
        
    } catch (AddressException e) {
        e.printStackTrace();
    } catch (MessagingException e) {
        e.printStackTrace();
    }
    //Creamos un objeto 'Transport', y ejecutamos la emision del correo a través de sus metodos.
    try {
        Transport t = session.getTransport("smtp");
        t.connect("dar10comyr@gmail.com", "blogspot2016");
        t.sendMessage(message, message.getAllRecipients());
        t.close();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    } catch (MessagingException e) {
        e.printStackTrace();
    }
    }
}

Comparte esto:

[Métodos] Java Mail Parte II - Enviar Mensaje


Para poder enviar un correo electronico con JavaMail, necesitaremos realizar 4 pasos:
  1. Crear una sesión de mail, seteando algunas propiedades.
  2. Construir objeto MimeMessage, con el objeto session.
  3. Al mensaje le seteamos emisor, destinatario, CC, Asunto, Mensaje.
  4. Creamos un objeto 'Transport', y ejecutamos la emision del correo a través de sus metodos.

1 - Creando una sesión


El primer paso es crear una sesión de la clase javax.mail.Session
  • public static Session getDefaultInstance(Properties props)
    • Obtiene el objeto de sesión predeterminado. Si aún no ha sido configurado uno previamente, se crea un nuevo objeto Session y se instala por defecto.
    • parámetros:
    • java.util.Properties props- Propiedades del objeto. Sólo se utiliza si se crea un nuevo objeto Session.
    • Devuelve:
    • Un objeto javax.mail.Session

Session session = Session.getDefaultInstance(misPropiedades);
session.setDebug(true);

setDebug(true) es una buena opción para mirar en la consola o en los archivos de logeos que es lo que va haciendo la sesión para construir e enviar el mensaje.

El objeto misPropiedades deberemos crearlo con las propiedades del servidor de correo electronico, para el caso de 'gmail':

Properties misPropiedades = new Properties();
// NOMBRE DEL HOST DEL CORREO, es smtp.gmail.com
misPropiedades.setProperty(mail.smtp.host", "smtp.gmail.com");
// TLS SI ESTA DISPONIBLE
misPropiedades.setProperty("mail.smtp.starttls.enable", "true");
// NUMERO DE PUERTO SMTP
misPropiedades.setProperty("mail.smtp.port", "587");
// NUESTRO CORREO ELECTRONICO
misPropiedades.setProperty("mail.smtp.user", "dar10comyr@gmail.com");
// AUTENTICACION PARA CONECTARSE, USUARIO Y CONTRASEÑA
misPropiedades.setProperty("mail.smtp.auth", "true");


Para otros servidores de correos electronicos las propiedades prodrian ser:

YAHOO MAIL OUTLOOK
mail.smtp.host smtp.mail.yahoo.com smtp-mail.outlook.com
mail.smtp.starttls.enable Si(Si está disponible.) Si
mail.smtp.port 465 o 587 587 (También se puede usar el puerto 25 como alternativa)
mail.smtp.auth Si


2 - Creando una MimeMessage


  • public MimeMessage(Session session)
    • constructor por defecto. Se crea un objeto MimeMessage vacío. El campo 'headers' se establece en un objeto InternetHeader vacío. El campo 'flag' se establece en un objeto Flags vacío. La bandera modified se establece en true.
    • Parámetros:
    • La session creada recientemente
    • Devuelve:
    • Una instancia de la clase MimeMessage para setear.

MimeMessage message = new MimeMessage(session);


3- Seteamos las opciones de envio


A este objeto hay que setearle los datos basicos para enviar un correo electronico, de la misma forma que otros clientes de correos electronicos ofrecen con una interfaz visual:


En nuestro codigo simplemente podriamos poner:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
try {
    message.setFrom(new InternetAddress("dar10comyr@gmail.com"));
    message.addRecipient(Message.RecipientType.TO, new InternetAddress("Destinatario@ejemplo.com"));
    message.addRecipient(Message.RecipientType.CC, new InternetAddress("CarbonCopy@ejemplo.com"));
    message.addRecipient(Message.RecipientType.BCC, new InternetAddress("BlindCarbonCopy@ejemplo.com"));
    message.setSubject("Hola");
    message.setText("Correo enviado con Java Mail =)");
} catch (AddressException e) {
    e.printStackTrace();
} catch (MessagingException e) {
    e.printStackTrace();
}


4- Crear objeto Transport


Para crear nuestro boton de 'enviar', le pedimos a la session que hemos creado que obtenga el transporte pasando por parámetro un string identificando 'Simple Mail Transfer Protocol'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
try {
    Transport t = session.getTransport("smtp");
    t.connect("dar10comyr@gmail.com", "lacontraseñadelmail");
    t.sendMessage(message, message.getAllRecipients());
    t.close();
} catch (NoSuchProviderException e) {
    e.printStackTrace();
} catch (MessagingException e) {
    e.printStackTrace();
}

  • Con el metodo connect identificamos quienes somos(correo y pass)
  • El metodo snedMessage hará la magia de enviar nuestro correo usando la libreria de JavaMail
  • No olvidemos cerrar la conexión con el método close

Luego de ejecutarlo, el resultado ha sido:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.dar10comyr.blogspot.red;

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MiMail {

    public static void main(String[] args) {
        enviarMail("dzubaray@gmail.com", "Mensaje de prueba", 
                "Probando el método \'enviarMail\'. \n Salu2");
    }
    
    public static void enviarMail(String Destinatario, String Asunto, String Mensaje){
        Properties misPropiedades = new Properties();
        misPropiedades.setProperty("mail.smtp.host", "smtp.gmail.com");
        misPropiedades.setProperty("mail.smtp.starttls.enable", "true");
        misPropiedades.setProperty("mail.smtp.port", "587");
        misPropiedades.setProperty("mail.smtp.user", "dar10comyr@gmail.com");
        misPropiedades.setProperty("mail.smtp.auth", "true");

        Session session = Session.getDefaultInstance(misPropiedades);
        session.setDebug(true);

        MimeMessage message = new MimeMessage(session);
        try {
            message.setFrom(new InternetAddress("dar10comyr@gmail.com"));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(Destinatario));
            message.setSubject(Asunto);
            message.setText(Mensaje);
        } catch (AddressException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }

        try {
            Transport t = session.getTransport("smtp");
            t.connect("dar10comyr@gmail.com", "**********");
            t.sendMessage(message, message.getAllRecipients());  
            t.close();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

Comparte esto:

[Métodos] Java Mail - Parte I


JavaMail es una expansión de Java que facilita el envío y recepción de e-mail desde código java. Implementa el protocolo SMTP (Simple Mail Transfer Protocol) así como los distintos tipos de conexión con servidores de correo -TLS, SSL, autentificación con usuario y password, etc-

JavaMail no se incluye en la JDK ni en la JRE, sino que debe conseguirse como un paquete externo. Debe, además, descargarse adicionalmente el JavaBeans Activation Framework en caso de usar una JDK inferior a la versión 6.
Para descargarlo acostumbro usar el repositorio de maven :


Simplemente dando a click a 'download(JAR)', tmb se puede hacer un proyecto maven e incluir el trozo de codigo en el pom. Lo mismo para Java JavaBeans(TM) Activation Framework.

Incluyendo Dependencias


  1. Click en File desde el menú de archivos
  2. 'Project Structure' (CTRL + SHIFT + ALT + S on Windows/Linux, + ; on Mac OS X)
  3. Seleccionar Modules en el panel de la izquierda.
  4. Vamos a la pestaña de 'Dependencies'
  5. hacemos click en '+' y luego → JARs or directories
  6. Buscamos nuestros JARs y listo!

Desde el viejo y querido Eclipse:
  1. Click derecho sobre el projecto y luego en 'propiedades'
  2. Luego vamos a el menu de la izquierda sobre Java Build Path
  3. Pestaña de 'Librerias' o 'Libreries' en nglés.
  4. Hacemos click sobre el botón de la derecha Add External JARs...
  5. Buscamos la ubicación y Listo

Para hacer lo propio desde NetBeans:


  1. Primero deberemos crear una libreria que contenga los JARs y luego agregar el mismo. Para ello vamos a menu 'tools' y sobre el menu desplegable damos a la opcion de Librarys
  2. en la parte inferior izquierda damos click sobre el boton New Library...


  3. Procedemos a darle un nombre que la identifique.
  4. Siguiente paso, sobre la pestaña de 'Classpath' vamos a hacer click sobre el boton Add JAR/Folder...


  5. Buscamos el jar donde se encuentre.
  6. Aceptamos y listo!

Otra manera es hacer de nuestro proyecto un Proyecto Maven, dejando que este se encargue de todas las dependencias configurando el archivo XML.


Configurando el MAIL

Unas de las cuestiones de usar por ejemplo GMAIL es que previamente hay que setearle un nivel de seguridad 'bajo' que nuestra aplicacion pueda hacer uso automatizado de cuenta.
Para ello vamos a el enlace: myaccount.google.com
Despues de loguearse, hay que ir a la opcion de 'Acceso y Seguridad'
Y en la opcion de 'Permitir el acceso a aplicaciones menos seguras', movemos el swicth para que si.

Java 25 de 2025