API JavaMail

Antes de profundizar en las classes de JavaMail, veremos las clases coraz�n que componen el API: Session, Message, Address, Authenticator, Transport, Store, y Folder. Todas estas clases se encuentran en el paquete del nivel superior del API JavaMail: javax.mail, aunque frecuentemente nos veremos utilizando clases del paquete javax.mail.internet.

.�Session

La clase Session define una sesi�n de correo b�sica. Es a trav�s de esta de sesi�n de la que todas las dem�s funcionan. El objeto Session se aprovecha de un objeto java.util.Properties para obtener informaci�n como el servidor de correo, el nombre de usuario, la password, y otra informaci�n que puede compartirse a lo largo de toda la aplicaci�n.

El constructor para las clases es privado. Podemos obtener una sola sesi�n por defecto que puede ser compartida con el m�todo getDefaultInstance():

Properties props = new Properties();
// fill props with any information
Session session = Session.getDefaultInstance(props, null);

O podemos crear una �nica sesi�n con getInstance():

Properties props = new Properties();
// fill props with any information
Session session = Session.getInstance(props, null);

En ambos casos el argumento null es un objeto Authenticator que no se utiliza en este momento, lo veremos m�s adelante en Authenticator.

En la mayor�a de los casos, es suficiente usar la sesi�n compartida, incluso si se trabaja con una sesi�n de correo para m�ltiples mailboxes de usuario. Podemos a�adir una combinaci�n de nombre de usuario y passsword en un paso posterior en el proceso de comunicaci�n, manteniendolo todo separado.

.�Message

Una vez que tenemos nuestro objeto Session, es hora de empezar a crear un mensaje para enviar. Esto se hace con un objeto Message.

Siendo una clase abstracta, debemos trabajar con una subcalse, en la mayor�a de los casos ser� javax.mail.internet.MimeMessage.

Un MimeMessage es un mensaje de e-mail que entiende los tipos MIME, definidos en las distintas RFCs. Las cabeceras de mensajes est�n restringidas a caracteres US-ASCII, aunque en ciertos campos de cabecera se pueden codificar caracteres no ASCII.

Para crear un Message, le pasamos el objeto Session al constructor de MimeMessage:

MimeMessage message = new MimeMessage(session);
Nota: Hay otros constructores, como para crear mensajes desde streams de entrada formateados RFC822.

Una vez que tenemos nuestro mensaje, podemos configurar sus diferentes partes, como Message implementa el interface Part (con MimeMessage implementando MimePart).

El mecanismo b�sico para configurar el contenidos es el m�todo setContent(), con los argumentos para el contenido y tipo mime:

message.setContent("Hello", "text/plain");

Sin embargo, si sabemos que est�mos trabajando con un MimeMessage y nuestro mensaje es texto plano, podemos usar su m�todo setText() que s�lo requiere el contenido real, dejando por defecto el tipo MIME a text/plain:

message.setText("Hello");

Para mensajes de texto plano la �ltima forma es el mecanismo preferido para seleccionar el contenido. Para enviar otros tipos de mensajes, como HTML, usaremos el formador, que veremos m�s adelante.

Para seleccionar el subject, usamos el m�todo setSubject():

message.setSubject("First");

.�Address

Una vez que hemos creado la Session y el Message, y tambi�n hemos rellenado el mensaje con contenido, es hora de poner direcci�n a nuestra carta con un objeto Address.

Como Message, Address es una clase abstracta. Usaremos la clase javax.mail.internet.InternetAddress.

Para crear una direcci�n con s�lo la direcci�n e-mail, se la pasamos al constructor:

Address address = new InternetAddress("[email protected]");

Si queremos que aparezca el nombre junto a la direcci�n e-mail, tambi�n podemos pas�rselo al constructor:

Address address = new InternetAddress("[email protected]", "George Bush");

Necesitaremos crear objetos address para los campos from y to del mensaje. A menos que el servidor lo evite, no hay nada que nos impida enviar un mensaje que parezca que viene de otra persona.

Una vez que hemos creado las direcciones, las conectamos al mensaje de una de estas dos formas. Para identificar al que lo env�a, usamos los m�todos setFrom() y setReplyTo().

message.setFrom(address)

Si nuestro mensane necesita varias direcciones "from", usamos el m�todo addFrom():

Address address[] = ...;
message.addFrom(address);

Para identificar a los receptores del mensaje, usamos el m�todo addRecipient(). Este m�todo requiere un Message.RecipientType junto a la direcci�n.

message.addRecipient(type, address)

Los tres tipos predefinidos de direcciones son:

  • Message.RecipientType.TO
  • Message.RecipientType.CC
  • Message.RecipientType.BCC

Por eso, si el mensaeje fuera dirigido al vice-presidete, enviando copia a la primera dama, esto ser�a lo apropiado:

Address toAddress = new InternetAddress("[email protected]");
Address ccAddress = new InternetAddress("[email protected]");
message.addRecipient(Message.RecipientType.TO, toAddress);
message.addRecipient(Message.RecipientType.CC, ccAddress);

El API JavaMail no proporciona mecanismo para chequear la validez de una direcci�n e-mail. Pero si podemos hacer que nuestro programa soporte un scan de caracteres v�lidos (seg�n lo definido en la RFC 822) o verificar nosotros mismos el registro MX (Mai Exchange), esto va m�s all� del �mbito del API JavaMail.

.�Authenticator

Como las clases java.net, el API JavaMail peude aprovecharse de un Authenticator para proteger accesos a recursos mediante un nombre de usuario y una password. Para el API JavaMail, el recursos es el servidor de correo. El Authenticator JavaMail se encuentra en el paquete javax.mail y es diferente de la clase de java.net con el mismo nombre. Las dos no comparten el mismo Authenticator ya que el API JavaMail funciona con Java 1.1, que no ten�a la veriedad java.net.

Para usar el Authenticator, subclasificamos la clase abstracta y devolvemos un ejemplar PasswordAuthentication del m�todo getPasswordAuthentication(). Debemos registrar el Authenticator con la sesi�n cuando se crea. Luego, nuestro Authenticator ser� notificado cuando sea necesaria una autentificaci�n. Podr�amos mostrar una ventana o leer el nombre de usuario y la password desde un fichero de configuraci�n (aunque si no est� encriptado no es seguro), devolviendolo al llamador como un objeto PasswordAuthentication.

Properties props = new Properties();
// fill props with any information
Authenticator auth = new MyAuthenticator();
Session session = Session.getDefaultInstance(props, auth);

.�Transport

La parte final del env�o de un mensaje es usar la clase Transport. Estas clase habla el lenguaje espec�fico del protocolo para enviar mensajes (normalmente SMTP). Es una clase abstracta y funciona como Session.

Podemos usar la versi�n por defecto de la clase s�lo llamando al m�todo est�tico send():

Transport.send(message);

O, podemos obtener un ejemplar espec�fico desde la sesi�n para nuestro protocolo, pas�ndole el nombre de usuario y la password (en blanco si no son necesarias), enviar el mensaje, y cerrar la conexi�n:

message.saveChanges(); // implicit with send()
Transport transport = session.getTransport("smtp");
transport.connect(host, username, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();

Esta �ltima forma es mejor cuando necesitamos enviar varios mensajes, porque mantendr� activa la conexi�n entre mensajes. El mecanismo b�sico send() hace un conexi�n separada al servidor para cada llamada a m�todo.

Nota: Para ver los comandos enviados al servidor de correo activaremos la bandera debug con session.setDebug(true).

.�Store y Folder

Obtener los mensajes empieza de forma similar a enviar mensajes, con una Session.

Sin embargo, despu�s de obtener la sesi�n, conectamos a un Store, probablemente con un nombre de usuario y una password o Authenticator. Como con Transport, le decimos al Store qu� protocolo utilizar:

// Store store = session.getStore("imap");
Store store = session.getStore("pop3");
store.connect(host, username, password);

Despu�s de conectar al Store, podemos obtener un Folder, que debe estar abierto antes de poder leer los mensajes que hay en su interior:

Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Message message[] = folder.getMessages();

Para POP3, la �nica carpeta disponible es INBOX. Si estamos usando IMAP, podremos disponer de otras carpetas.

Nota: Los proveedores de Sun se han pensado para ser inteligentes. Mientras que Message message[] = folder.getMessages(); podr�a parecer una operaci�n lenta que lee todos los mensajes del servidor, s�lo cuando realmente necesitamos obtener una parte del mensaje es cuando el contenido es recuperado.

Una vez que tenemos un Message para leer, podemos obtener sus contenidos con getContent() o escribir sus contenidos en un stream con writeTo(). El m�todo getContent() s�lo obtiene el contenido del mensaje, mientras que la salida de writeTo() incluye las cabeceras.

System.out.println(((MimeMessage)message).getContent());

Despu�s de haber le�do el e-mail, cerramos la conexi�n al folder y al store.

folder.close(aBoolean);
store.close();

El valor boolenao pasado al m�todo close() del folder significa si actualizamos o no la carpeta eliminando los mensajes borrados.

.�M�s all�

Esencialmente, entender c�mo usar las siete clases es todo lo que necesitamos para manejar el API JavaMail. La mayor�a de las otras capacidades del API JavaMail construidas desde estas siete clases hacen algo un poco diferente o de una forma particular, como si el contenido es un attachment. Ciertas tareas, como las b�squedas, est�n aisladas y se describen en la secci�n Busquedas por SearchItem.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO