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://MYUSERNAME@gmail.com:MYPASSWORD@imap.gmail.com");
    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 ).


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.


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)


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%40gmail.com@imap.gmail.com/INBOX.

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


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");

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 .


2

Esto es lo que funcionó para mi equipo y para mí, con una cuenta clásica nickname@gmail.com y una cuenta comercial employee@business.com:

            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 = "employee@business.com" 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 :


¿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"


0

Necesita tener JSSE instalado para usar SSL con Java


0
URLName server = new URLName("imaps://<gmail-user-name>:<gmail-pass>@imap.gmail.com/INBOX");
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.