Disponible en descarga gratuita Cuadernos de Viaje - Oriente Próximo, el libro con nuestras aventuras en Jordania, Siria e Israel.

viernes, 31 de agosto de 2007

Enviar un correo electrónico desde Java

Esto es algo que he tenido que hacer muchas veces y que, la verdad, es de lo más sencillo. El problema de las cosas que son sencillas es que tienen a olvidarse porque "es tan fácil que no merece la pena". Luego llega el momento de volverlo a hacer, recuerdas que era fácil y dices que tardarás muy poco en hacerlo. Y te pones a hacerlo y te das cuenta de como era tan fácil no pusiste mucha atención en memorizar los pasos y que, al final, lo mismo te pasas del tiempo que has dicho.

Yo tengo una clase utilidad que aparte de hacer más cosas envía correos desde Java. Las otras cosas que hace son abrir una conexión a una base de datos, manejar formatos de fechas,... Pero no siempre llevo la clase encima. De todas formas, incluso llevándola hacen falta algunas cosas más. Dos cosas más: dos librerías de java:
activation.jar JavaBeans Activation Framework
mail.jar JavaMail

Una vez colocados ambos jars en el classpath del proyecto bastará con llamar a los métodos de la clase EnvioCorreo:
package com.jaac.utilidad;

import java.io.FileInputStream;
import java.util.Properties;

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


/**
 * @author JAAC
 *
 */
public class EnvioCorreo {

final static String CONFIG_FILE = "mail.props";
static String sServidorCorreo;
static String sCorreoOrigen;
static String[] asCorreoDestino;

    /**
     * Método para inicializar los valores del seridor de correo,
     * se cargan desde un fichero de configuración con los siguientes valores:
     * app.servidorCorreo=smtp.xxxx
     * app.correoOrigen=origenxxx@xxx.com
     * app.correoDestino=dst1@xxx.com,dst2@xxx.com,...,dstn@xxx.com
     */
public static void init () {
    try
    {
        Properties props = new Properties();
        props.load( new FileInputStream( CONFIG_FILE ) );
       
        sServidorCorreo = props.getProperty( "app.servidorCorreo" );
        sCorreoOrigen = props.getProperty( "app.correoOrigen" );
        String sTmp = props.getProperty( "app.correoDestino" );
        String[] asTmp = null;
        if( sTmp.indexOf( "," ) != 1 ) {
            asTmp = sTmp.split( "," );
        }
        else
        {
            asTmp = new String[1];
            asTmp[0] = sTmp;
        }
        asCorreoDestino = asTmp;
    }
    catch( Exception ex )
    {
        System.out.println( "No hay información de arranque!!" );
        System.exit( -2 );
    }

}

    /**
     * Método público y estático que envía un correo a las direcciones
     * indicadas en el fichero de propiedades, desde la dirección indicada
     * también en el mismo fichero con el asunto y el contenido que se pasan
     * como parámetros.
     * 
     * @param sAsunto String
     * @param sTexto String
     * @return boolean
     */
public static boolean enviarEmail( String sAsunto, String sTexto )
{
    try
    {
        Properties props = new Properties();
        props.put("mail.smtp.host", sServidorCorreo );
        Session mailSesion = Session.getDefaultInstance(props, null);

        Message msg = new MimeMessage(mailSesion);
   
        msg.setFrom ( new InternetAddress( sCorreoOrigen ) );
        msg.setSubject ( sAsunto );
        msg.setSentDate ( new java.util.Date() );
        msg.setText ( sTexto );

        InternetAddress address[] = new InternetAddress[asCorreoDestino.length];
        for( int i = 0; i <> asCorreoDestino.length; i++ ) {
            address[i] = new InternetAddress ( asCorreoDestino[i] );
        }         
           
        msg.setRecipients (Message.RecipientType.TO, address);

    // Modificación para envío de adjuntos propuesta por Elisa

        Multipart m = new MimeMultipart();
        MimeBodyPart mb = new MimeBodyPart();
        mb.attachFile(archivo);
        m.addBodyPart(mb);
        msg.setContent(m);

    // Fin modificación para envío de adjuntos propuesta por Elisa
          
        Transport.send(msg);
      }
      catch( MessagingException e )
      {
          return false ;
      }
   
      return true ;
  }

}

51 comentarios:

Lord Maelwys dijo...

muchas gracias por el aporte

Luis Geovanni dijo...

Buen aporte, solo quisiera molestarte, para que me explicaras mejor lo de las dos utilidades o librerias faltantes, a las que te referis, no se donde encontrarlas y en donde se instalan o colocan, yo quiero usar NetBeans para hacer este proyectito, pero no se que me aconsejas?? estaré muy agradecido por la respuesta

JAAC dijo...

Hola Luis, los jar que hacen falta son activation.jar y mail.jar. Busca en google que los encontrarás para descargar.
En NetBeans añades los jar al proyecto y los incluyes en el classpath y listo. Yo uso eclipse, pero es prácticamente igual.

Anónimo dijo...

Hola, resulta que en la linea de codigo
props.put("mail.smtp.host", sServidorCorreo );
me genera una NullPointerException, pero no tengo idea porque, por favor aclarame algo, gracias.

JAAC dijo...

Sólo se me ocurre que no hayas puesto en el fichero de propiedades un valor para el servidor de correo y que al cargarlo haya quedado como null.
Comprueba el fichero de propiedades/parámetros: "mail.props".

noemi dijo...

a mi no me funciona me dice que no tiene el metodo main y si lo pongo tampoco funciona... alguien me puede ayudar

JAAC dijo...

Noemi es una clase de utilidad, por eso no tiene main.

En tu programa tendrás tu main que llamará al método init de la clase EnvioCorreo, que cargará la información del servidor de correo y de las cuentas de origen y destino. Después, cada vez que quieras enviar un correo, llamarás a enviarEmail con los parámetros de asunto y texto del mensaje.

noemi dijo...

necesito ayuda... me dice que no hay informacion de arranque... como le cargo la informacion??? necesito respuesta rapida...Gracias

JAAC dijo...

¿Has creado y rellenado el fichero de configuración que lee al principio (mail.props) y es accesible desde el programa?

El fichero tiene que ser como aparece en el comentario:
app.servidorCorreo=nombreServidor
app.correoOrigen=direccionOrigen
app.correoDestino=direccionDestino,direccionDestino,direccionDestino,...

Edwin dijo...

Hola JAAC, he copiado tu ejemplo, lo he implementado pero me sale este error, espero puedas darme una mano
09/09/22 16:15:29 javax.mail.SendFailedException: Sending failed;
nested exception is:
class javax.mail.SendFailedException: Invalid Addresses;
nested exception is:
class javax.mail.SendFailedException: 550-Message rejected because (edwin) [190.233.64.142]:10711 is blacklisted at
550 rbl.davetha.com see Blocked - see http://www.spamcop.net/w3m?action=checkblock&ip=190.233.64.142

JAAC dijo...

Hola Edwin,

Lo que te está pasando es que tu ip está en una lista negra y por eso te está rechazando los correos el servidor al que los mandas. No es problema del código.

550-Message rejected because (edwin) [190.233.64.142]:10711 is blacklisted at
550 rbl.davetha.com see Blocked - see http://www.spamcop.net/w3m?action=checkblock&ip=190.233.64.142

Ve a la URL que te indica, supongo que habrá alguna manera de borrarte de la lista. También es posible que ya esté borrada tu ip automáticamente al haber pasado un día.

Christian dijo...

Muchas gracias por el aporte. Es cierto eso de que las cosas faciles siempre se olvidan.
A mi me funciona perfectamente, creo que voy a crearme un .jar con todas estas utilidades "faciles" y llevarlo siempre conmigo

JAAC dijo...

Gracias a ti por escribir Christian. Me alegro de que te haya resultado útil.

Mario Germán dijo...

Hola JAAC, me sirvio mucho tu articulo, ya lo implemente y me funciono, pero tengo una pregunta, el prgrama como obtiene la contrasea de correo?.

Gracias de antemano

JAAC dijo...

Mario, esto se suele usar dentro de una empresa por lo que la autenticación contra el servidor no requiere contraseña. En el caso de estar la tendrías que leer del fichero de propiedades.

Mario Germán dijo...

Gracias por aclararme la duda y por el codigo, me hizo mucha ayuda.

Pablo dijo...

pues a mi me da un fallo en la linea 87

for (int i = 0;i <> asCorreoDestino.length;i++) {

misterios...
illegal start of expresions .....

Pablo dijo...

pues a mi me da un fallo en la linea 87

for (int i = 0;i <> asCorreoDestino.length;i++) {

misterios...
illegal start of expresions .....

JAAC dijo...

Hola Pablo, pues no sé qué decirte. El código tal y como está compila normalmente, comprueba que no se te haya copiado algún carácter de control y esté molestando al compilador.

_-_-Luiz-_-_ dijo...

hola JAAC ami tambn me genera un error en la misma linea
for( int i = 0; i < asCorreoDestino.length; i++ )
talvez lo que pase es que los operadores <> esten mal colocados ya q el compilador de java no detecta este tipo de funcion de operadores pero si lo modificas por for( int i = 0; i < asCorreoDestino.length; i++ ) talvez funcione ;)

oye necesito ayuda para configurarlo mi correo es kriptos_luis_17@hotmail.com please! es q estoy desarrollando un sistema de seguridad y la notificacion por correo es la unica que me falta!

_-_-Luiz-_-_ dijo...

aa y gracias por el aporte ;)

JAAC dijo...

Hola Luiz,

En principio ese código compila, lo que comentas de los operadores no lo veo, además de que el código que dices que tal vez funcione es el mismo :-O

La configuración es sólo rellenar el fichero de parámetros, es muy sencilla. De todas formas piensa que este código es muy antiguo y puede que algo esté deprecado en Java, pero la idea es la misma.

Gracias a ti por pasar.

Mario Germán dijo...

Yo lo he usado hace unos meses y lo tengo en un batch q me corre a diario y no ha dado problema, voy a hecharle un ojo para ver cual es el problema, pero creo q como esta deberia funcionar.

_-_-Luiz-_-_ dijo...

Ola ps no he podido hacer que funcione!! no se si sea por que necesito un host de gmail o por que por que he tratado de enviar de hotmail y nada mas no me envia nada!!! espero y me puedas ayudar!!! en mi problema! please!

Mario Germán dijo...

Pues la verdad me esta funcionando, pense que podia ser porq el correo era de gmail o hotmail pero me funciona igual.

Mario Germán dijo...

Hola JAAC como he dicho lo he porbado y funcionado, no se si sabes como es la teoria de esto, pero tengo una duda. Yo accedo al servidor de la empresa y por este me puedo enviar un correo desde gmail sin necesidad de la contraseña, como hace el codigo o el servidor de la empresa para acceder al servidor de gmail para enviar el correo desde ahi?.

Mario Germán dijo...

JAAC ya encontre la explicacion en la wiki, perdon por molestar.

Anónimo dijo...

hola JAAC.. gracias por el aporte, funciona excelente, justo lo que necesitaba!!

Anónimo dijo...

hola como haria para enviar un archivo adjunto en este codigo.???

JAAC dijo...

Pues nunca he mandado un adjunto desde Java, pero aquí tienes más información.

Alexander dijo...

Hola, me gustaría saber como hago para incluir en el CLASSPATH los .jar que mencionas. Busque por toda la red y al final terminé rindiendome, gracias.

JAAC dijo...

Hola Alexander, depende de lo que estés utilizando. Desde línea de comandos se incluye el párametro -cp y los directorios (separados por puntos y coma en Windows, y por dos puntos en sistemas Linux/Unix).

Alex dijo...

Hay muchos programas interesantes para solucionar esta problema. Pero una utiliza puede ayudar en complejidad dada entre par minutos. Encontre esta utiliza en un soft archivo - reparar bandeja de entrada.dbx.

Anónimo dijo...

Hola JAAC muchas gracias por el aporte, tengo un problema ojala puedas ayudarme, al utilizar el codigo me sale esta excepcion:
javax.mail.MessagingException: Can't send command to SMTP host;
nested exception is:
java.net.SocketException: Software caused connection abort: socket write error
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2106)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2093)
at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1184)
at javax.mail.Transport.send0(Transport.java:197)
at javax.mail.Transport.send(Transport.java:124)
at EnvioCorreo.enviarEmail(EnvioCorreo.java:73)
at Correo.main(Correo.java:11)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at com.sun.mail.util.TraceOutputStream.write(TraceOutputStream.java:114)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2104)
... 6 more
Te agradezco de antemano, saludos!!

bga dijo...

JAAC, muchas gracias por tu aporte. Que bueno que existan personas dispuestas a compartir su trabajo y conocimiento!!!

JAAC dijo...

Hola bga, gracias a ti por comentar y me alegra de que te haya sido útil.

Elisa dijo...

hola para los q requieren enviar archivos adjuntos les paso el tip basándonos en el código de JAAC en el método enviarMail agregar líneas


Multipart m = new MimeMultipart();
MimeBodyPart mb = new MimeBodyPart();
mb.attachFile(archivo);
m.addBodyPart(mb);
msg.setContent(m);

espero q les sirva =)

JAAC dijo...

Muchas gracias Elisa!
Ahora lo copio en el código :-)

Víctor dijo...

Hola, que tal.

Me parece muy buena clase de utilidad.
Tengo un pequeño problemita al momento de correrla, me marca el siguiente error:
Caused by: java.lang.ClassNotFoundException: com.sun.mail.util.MessageRemovedIOException
y no se a que se debe,

te agradesco de antemano la ayuda.

saludos

Víctor dijo...

Aqui de nuevo, ya solucione mi problema, no habia puesto el mail.jar


Graias por el apunte, esta muy bueno y practico (Y)

JAAC dijo...

Me alegra de que te sea útil Víctor! y perfecto que lo hayas resuelto :-)

Diie dijo...

Buenas . El código me viene muy bien para el juego que estoy haciendo, y el programa compila perfectamente. El problema es que no me envía ningún mail, o sea, envié un mail de prueba a mi correo y no me llega :s no se si será porq estoy poniendo mal algún parámetro. Te molestaría poner un ejemplo? Tal vez no me envía el mail porq no he escrito bien el parámetro del smtp, o no estoy usando debidamente el código.
Lo que hice en mi Main fue lo siguiente:
Mail m=new Mail();
String[] destino=new String[1];
destino[0]="mimail@hotmail.com";
m.asCorreoDestino=destino;
m.sCorreoOrigen="mimail@hotmail.com";
m.sServidorCorreo="smtp.live.com";
m.enviarEmail("prueba", "OK");
tal vez puedas decirme el error que estoy cometiendo. gracias por la ayuda, y espero que me puedas responder pronto

Jorge dijo...

Que funcion tiene activation.jar ya que no usa ninguna libreria desde el netbeans funciona pero desde la consola no y ya verfique el classpath y esta igual que en el proyecto, tengo que tener corriendo un servidor de correo si uso smtp de gmail .Gracias el error que me da es

Microsoft Windows XP [Versión 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\JORGE>java -jar "C:\EnvioMail\dist\EnvioMail.jar"
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/BAS
E64EncoderStream
at javax.mail.internet.MimeMessage.setSubject(MimeMessage.java:793)
at javax.mail.internet.MimeMessage.setSubject(MimeMessage.java:757)
at enviomail.Main.main(Main.java:46)
Caused by: java.lang.ClassNotFoundException: com.sun.mail.util.BASE64EncoderStre
am
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at sun.misc.Launcher$ExtClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 3 more

Anónimo dijo...

Buenas tardes JAAC. Mira es que me marca un error al inicio, estoy usando NetBeans. en la parte donde esta:

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

Se subrayan en color amarillo y no se que hacer, ya importe el activation.jar y el mail.jar. Muchas gracias

JAAC dijo...

No uso NetBeans, pero en Eclipse, cuando algo aparece subrayado en amarillo no es un error, es que todavía no se usa y te avisa de que lo puedes borrar...
¿Has copiado todo el código?

Anónimo dijo...

Asi es, copie todo el código y me sale eso.

Anónimo dijo...

Muchas gracias por compartir JAAC! Ha funcionado de maravilla :)

Anónimo dijo...

Podrias poner un ejemplo No consigo saber donde poner lo del servidor

Diego Forlan dijo...

disculpa amigo me sale este error:

com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. n20sm12776920anl.19

que seria la causa de ello?

Luis Llumitaxi dijo...

Una consulta..necesito enviar una notificación al correo...de productos que se estan agotando..en que me puedo basar para determinar el tiempo de envio de esas notificaciones..o cada que tiempo se puede enviar???

raybanoutlet001 dijo...

oakley sunglasses
coach outlet
air max 90
nike huarache
louis vuitton pas cher
reebok shoes
ugg boots
ugg boots
michael kors outlet store
ralph lauren