Las librerías son un conjunto de métodos y atributos que permiten una funcionalidad concreta dentro de una aplicación. En java inicialmente están incluidas las librerías básicas para la funcionalidad «corriente» de cualquier aplicación pero si se quiere añadir funcionalidad se debe importar la librería concreta para así disponer de los métodos y atributos que dan la funcionalidad deseada. Para poder importar una librería depende del método en el que esté creado el proyecto (maven, gradle, etc…) pero de forma genérica se pueden agregar en el menú de proyect structure en la parte de libraries. En el caso de ser un proyecto maven o gradle tan solo hay que indicar la dirección a la cual se debe conectar el proyecto para obtener las librerías. En el caso de querer importar un .jar tan solo se debe indicar la ruta donde se encuentra dicho archivo. En este ejemplo se utilizará la librería oficial de Oracle JavaMail, descargada de https://javaee.github.io/javamail/#Download_JavaMail_Release

JavaMail

JavaMail permite enviar y recibir correos electrónicos desde imap, pop3, smtp de forma sencilla con todas las características que el servidor de correo permita. Para este ejemplo se utilizará la siguiente interfaz que recoge todas las posibilidades

En este ejemplo se utilizarán los parámetros del servidor de gmail mediante smtp, pero es configuraba a cualquier protocolo. Lo primero que se debe realizar es permitir a la cuenta de correo que se vaya a utilizar el acceso a aplicaciones externas, ya que sin eso no será capaz de realizar una conexión efectiva. Esto se realiza desde el siguiente enlace https://myaccount.google.com/u/3/lesssecureapps?pli=1 . Una vez activada esta opción ya se puede realizar el envío de mensajes. Toda aplicación de JavaMail consta de los siguientes pasos:

  • Declaración de parámetros

Se realiza mediante un objeto de tipo properties donde se asocia un par clave – valor a cada una de las configuraciones necesarias para los siguientes pasos

properties = new Properties();
properties.put("mail.smtp.host", "smtp.gmail.com");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.port", "587");
properties.put("mail.smtp.auth", "true");
properties.put("mail.user", "developandsystem@gmail.com");
properties.put("mail.password", "password");
  • Apertura de la sesión

Una vez declaradas las propiedades se abre la sesión para poder enviar el mensaje. Hay que tener en cuenta que dejar una sesión abierta puede ser peligroso, por lo que se recomienda que una vez utilizado el objeto de tipo session se cierre

Session session = Session.getInstance(properties, null);;
  • Construcción del mensaje

Con la sesión abierta tan solo queda construir el mensaje con cada una de las partes del mismo. Esto se realiza mediante un objeto de tipo MimeMessage al cual se le pasa en constructor la sesión abierta. Una vez creado el objeto se asignan todos los datos que contendrá el mensaje. En el siguiente código se crea un mensaje con emisor, receptor, asunto y mensaje simple.

MimeMessage mimeMessage = new MimeMessage(session);
try {
    mimeMessage.setText(texto.getText());
    mimeMessage.setFrom(new InternetAddress("developandsystem@gmail.com"));
    InternetAddress[]direcciones= new InternetAddress[]{new InternetAddress(txtPara.getText().toString())};
    mimeMessage.setRecipients(Message.RecipientType.TO,direcciones);
    mimeMessage.setSubject(txtAsunto.getText().toString()) 
    } 
catch (MessagingException e1) {
    e1.printStackTrace();
}
  • Envio del mensaje

Por último mediante un objeto de tipo Transport se envía el mensaje con toda la información añadida en el paso anterior.

Transport transport = session.getTransport("smtp");
transport.connect(properties.getProperty("mail.user"), properties.getProperty("mail.password"));
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
transport.close();

Adjuntar un archivo

Como se ha visto a la hora de construir el mensaje, se hacia mediante un objeto de tipo MimeMessage donde se asociaban todos los datos. El texto se ha puesto mediante el método setText() ya que se trataba únicamente de texto plano pero si se quiere construir un correo completo (con archivos adjuntos o varias partes de texto) se debe hacer mediante un objeto de tipo MimeBodyPart donde se MimeMultipart donde se asocian las partes del mensaje y se pone como setContent dentro del MimeMessage

MimeMultipart mimeMultipart = new MimeMultipart();
MimeBodyPart mimeBodyPartTexto = new MimeBodyPart();
mimeBodyPartTexto.setText(texto.getText().toString());
MimeBodyPart mimeBodyPartAdjunto = new MimeBodyPart();
mimeBodyPartAdjunto.attachFile(adjunto);
mimeMultipart.addBodyPart(mimeBodyPartAdjunto);
mimeMultipart.addBodyPart(mimeBodyPartTexto);
mimeMessage.setContent(mimeMultipart);

El código completo del ejemplo sería

public class VentanaMail extends JFrame implements ActionListener {
    private JPanel root;
    private JTextField txtPara;
    private JTextField txtCC;
    private JTextField txtCCO;
    private JButton btnAdjunto;
    private JTextArea texto;
    private JButton enviar;
    private JButton borrarButton;
    private JTextArea txtAsunto;
    private JLabel txtRuta;
    File adjunto;
    Properties properties;
    Session session;


    public VentanaMail() throws HeadlessException {
        init();
        acciones();
    }

    private void acciones() {
        enviar.addActionListener(this);
        btnAdjunto.addActionListener(this);
    }

    private void init() {
        setContentPane(root);
        iniciarSesionGmail();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void iniciarSesionGmail() {
        properties = new Properties();
        properties.put("mail.smtp.host", "smtp.gmail.com");
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.user", "developandsystem@gmail.com");
        properties.put("mail.password", "password");
        session = Session.getInstance(properties, null);
        
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == btnAdjunto) {
            JFileChooser fileDialog = new JFileChooser();
            int opcion = fileDialog.showDialog(this,"Abrir");
            switch (opcion){
                case JFileChooser.APPROVE_OPTION:
                    adjunto = fileDialog.getSelectedFile();
                    txtRuta.setText(adjunto.getAbsolutePath());
                    break;
            }

        }
        else if (e.getSource() == enviar) {
            MimeMessage mimeMessage = new MimeMessage(session);
            try {
                //mimeMessage.setText(texto.getText());
                MimeMultipart mimeMultipart = new MimeMultipart();
                MimeBodyPart mimeBodyPartTexto = new MimeBodyPart();
                mimeBodyPartTexto.setText(texto.getText().toString());
                MimeBodyPart mimeBodyPartAdjunto = new MimeBodyPart();
                mimeBodyPartAdjunto.attachFile(adjunto);
                mimeMultipart.addBodyPart(mimeBodyPartAdjunto);
                mimeMultipart.addBodyPart(mimeBodyPartTexto);
                mimeMessage.setContent(mimeMultipart);

                mimeMessage.setFrom(new InternetAddress(properties.getProperty("mail.user")));
                //InternetAddress[] direcciones = new InternetAddress[]{new InternetAddress(txtPara.getText().toString())};
                mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(txtPara.getText()));
                mimeMessage.setRecipient(Message.RecipientType.CC,new InternetAddress(txtCC.getText()));
                mimeMessage.setRecipient(Message.RecipientType.BCC,new InternetAddress(txtCCO.getText()));
                mimeMessage.setSubject(txtAsunto.getText());
                Transport transport = session.getTransport("smtp");
                transport.connect(properties.getProperty("mail.user"), properties.getProperty("mail.password"));
                transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
                transport.close();
            } catch (MessagingException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
}