Obtener correo de GMail en la aplicación Java usando IMAP

76

Quiero acceder a los mensajes de Gmail desde una aplicación Java mediante JavaMail e IMAP . ¿Por qué obtengo una excepción SocketTimeoutException? ?

Aquí está mi código:

Properties props = System.getProperties();
props.setProperty("mail.imap.host", "imap.gmail.com");
props.setProperty("mail.imap.port", "993");
props.setProperty("mail.imap.connectiontimeout", "5000");
props.setProperty("mail.imap.timeout", "5000");

try {
    Session session = Session.getDefaultInstance(props, new MyAuthenticator());
    URLName urlName = new URLName("imap://[email protected]:[email protected]");
    Store store = session.getStore(urlName);
    if (!store.isConnected()) {
        store.connect();
    }
} catch (NoSuchProviderException e) {
    e.printStackTrace();
    System.exit(1);
} catch (MessagingException e) {
    e.printStackTrace();
    System.exit(2);
}

He configurado los valores de tiempo de espera para que no tarde "una eternidad" en el tiempo de espera. Además, MyAuthenticator también tiene el nombre de usuario y la contraseña, lo que parece redundante con la URL. ¿Existe otra forma de especificar el protocolo? (No lo vi en JavaDoc para IMAP ).

Dave
fuente
1
Si desea acceder a los subprocesos de GMail utilizando JavaMail, es posible que le interese code.google.com/p/java-gmail-imap
Mark McLaren
2
¿Alguna de estas soluciones basadas en IMAP ya funciona sin la necesidad de "Permitir aplicaciones menos seguras"?
jordanpg

Respuestas:

70

Usar imaps fue una gran sugerencia. Ninguna de las respuestas proporcionadas simplemente funcionó para mí, así que busqué en Google un poco más y encontré algo que funcionó. Así es como se ve mi código ahora.

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", "<username>@gmail.com", "<password>");
  ...
} catch (NoSuchProviderException e) {
  e.printStackTrace();
  System.exit(1);
} catch (MessagingException e) {
  e.printStackTrace();
  System.exit(2);
}

Esto es bueno porque elimina el Autenticador redundante de la imagen. Me alegro de que esto haya funcionado porque SSLNOTES.txt me hace girar la cabeza.

Dave
fuente
8

Debe utilizar las siguientes propiedades para imaps:

props.setProperty("mail.imaps.host", "imap.gmail.com");
props.setProperty("mail.imaps.port", "993");
props.setProperty("mail.imaps.connectiontimeout", "5000");
props.setProperty("mail.imaps.timeout", "5000");

Observa que es "imaps", no "imap", ya que el protocolo que está utilizando es imaps (IMAP + SSL)

WhyNotHugo
fuente
6

En JavaMail, puede utilizar imapscomo esquema de URL para utilizar IMAP sobre SSL. (Véase SSLNOTES.txten su distribución JavaMail para más detalles.) Por ejemplo, imaps://username%[email protected]/INBOX.

Del mismo modo, utilice smtpspara enviar correos electrónicos a través de Gmail. ej smtps://username%[email protected]/. Nuevamente, lea SSLNOTES.txtpara obtener más detalles. ¡Espero eso ayude!

Chris Jester-Young
fuente
3

Tienes que conectarte a GMail usando SSL únicamente. Establecer las siguientes propiedades lo forzará.

props.setProperty ("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty ("mail.imap.socketFactory.fallback", "falso");
Brian Matthews
fuente
No recomiendo este enfoque en general, porque anula todas las conexiones imap para que sean imaps. A veces, la elección es algo bueno, especialmente si el programa se va a utilizar para conectarse solo a Gmail. Sin embargo, si cree que IMAP simple es completamente incorrecto, entonces este enfoque es aceptable. :-)
Chris Jester-Young
... utilizado para conectarse a algo más que a Gmail, me refiero. :-P
Chris Jester-Young
2

Si desea más código de muestra sobre el uso de JavaMail con Gmail (por ejemplo, convertir etiquetas de Gmail en nombres de carpetas IMAP o usar IMAP IDLE), consulte mi programa GmailAssistant en SourceForge .

Zach Scrivena
fuente
2

Esto es lo que funcionó para mi equipo y para mí, con una cuenta clásica [email protected] y una cuenta comercial [email protected]:

            final Properties properties = new Properties();
            properties.put("mail.imap.ssl.enable", "true");

            imapSession = Session.getInstance(properties, null);
            imapSession.setDebug(false);
            imapStore = imapSession.getStore("imap");

            imapStore.connect("imap.gmail.com", USERNAME, "password");

con USERNAME = "nickname" en el caso clásico y USERNAME = "[email protected]" en el caso de la cuenta comercial.

En el caso clásico, y si usa una antigua dependencia de JavaMail, no olvide reducir la seguridad de la cuenta aquí: https://www.google.com/settings/security/lesssecureapps

En ambos casos, verifique en Configuración de GMail => Reenvío de POP / IMAP si IMAP está habilitado para la cuenta.

¡Espero eso ayude!

Para llegar más lejos :

lboix
fuente
¿Qué quiere decir con "antigua dependencia de JavaMail"? No creo que esto tenga nada que ver con la versión de JavaMail, es que te estás conectando con IMAPS en lugar de OAUTH2.
jordanpg
1

Usé las siguientes propiedades para obtener la tienda y funciona bien.

"mail.imaps.host" : "imap.gmail.com"
"mail.store.protocol" : "imaps"
"mail.imaps.port" : "993"

Alex Cheng
fuente
0

Necesita tener JSSE instalado para usar SSL con Java

hd1
fuente
0
URLName server = new URLName("imaps://<gmail-user-name>:<gmail-pass>@imap.gmail.com/INBOX");
Nishanthi Grashia
fuente