Neste artigo aprenderemos a utilizar algumas classes do pacote javax.mail para enviar e-mail em Java. Nosso projeto consistirá na construção de uma aplicação composto de apenas um formulário onde este formulário terá os campos e métodos responsáveis por enviar o e-mail.

Construindo o projeto

Nosso formulário após finalizado deverá ter a aparência da Figura 1.

Formulário FmainMail
Figura 1. Formulário FmainMail

O acionamento do botão enviar captura os dados dos campos assunto, e-mail destino e mensagem para enviar ao e-mail do destinatário.

Caso você esteja usando o Netbeans poderá utilizar o arquivo .form, descrito na Listagem 1, para montar seu formulário igualmente mostrado na Figura 1.


<?xml version="1.0" encoding="UTF-8" ?>
 
<Form version="1.3" maxVersion="1.9" 
type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
  <Properties>
    <Property name="defaultCloseOperation" type="int" value="3"/>
  </Properties>
  <SyntheticProperties>
    <SyntheticProperty name="formSizePolicy" 
    type="int" value="1"/>
    <SyntheticProperty name="generateCenter" 
    type="boolean" value="false"/>
  </SyntheticProperties>
  <AuxValues>
    <AuxValue name="FormSettings_autoResourcing" 
    type="java.lang.Integer" value="0"/>
    <AuxValue name="FormSettings_autoSetComponentName" 
    type="java.lang.Boolean" value="false"/>
    <AuxValue name="FormSettings_generateFQN" 
    type="java.lang.Boolean" value="true"/>
    <AuxValue name="FormSettings_generateMnemonicsCode" 
    type="java.lang.Boolean" value="false"/>
    <AuxValue name="FormSettings_i18nAutoMode" 
    type="java.lang.Boolean" value="false"/>
    <AuxValue name="FormSettings_layoutCodeTarget" 
    type="java.lang.Integer" value="1"/>
    <AuxValue name="FormSettings_listenerGenerationStyle" 
    type="java.lang.Integer" value="0"/>
    <AuxValue name="FormSettings_variablesLocal" 
    type="java.lang.Boolean" value="false"/>
    <AuxValue name="FormSettings_variablesModifier" 
    type="java.lang.Integer" value="2"/>
  </AuxValues>
 
  <Layout>
    <DimensionLayout dim="0">
      <Group type="103" groupAlignment="0" attributes="0">
          <Group type="102" alignment="0" attributes="0">
              <EmptySpace max="-2" attributes="0"/>
              <Group type="103" groupAlignment="0" attributes="0">
                  <Component id="jScrollPane1" max="32767" attributes="0"/>
                  <Group type="102" attributes="0">
                      <Group type="103" groupAlignment="0" attributes="0">
                          <Component id="jButtonEnviar" 
                          alignment="0" min="-2" max="-2" attributes="0"/>
                          <Component id="jLabel1" 
                          alignment="0" min="-2" max="-2" attributes="0"/>
                          <Component id="jTextFieldAssunto" 
                          alignment="0" min="-2" pref="280" max="-2" attributes="0"/>
                          <Component id="jLabel2" 
                          alignment="0" min="-2" max="-2" attributes="0"/>
                          <Component id="jTextFieldEmailDestino" 
                          alignment="0" min="-2" pref="280" max="-2" attributes="0"/>
                          <Component id="jLabel3" 
                          alignment="0" min="-2" max="-2" attributes="0"/>
                      </Group>
                      <EmptySpace min="0" pref="104" max="32767" attributes="0"/>
                  </Group>
              </Group>
              <EmptySpace max="-2" attributes="0"/>
          </Group>
      </Group>
    </DimensionLayout>
    <DimensionLayout dim="1">
      <Group type="103" groupAlignment="0" attributes="0">
          <Group type="102" alignment="1" attributes="0">
              <EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
              <EmptySpace max="-2" attributes="0"/>
              <Component id="jTextFieldAssunto" min="-2" max="-2" attributes="0"/>
              <EmptySpace type="separate" max="-2" attributes="0"/>
              <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
              <EmptySpace max="-2" attributes="0"/>
              <Component id="jTextFieldEmailDestino" min="-2" max="-2" attributes="0"/>
              <EmptySpace type="separate" max="-2" attributes="0"/>
              <Component id="jLabel3" min="-2" max="-2" attributes="0"/>
              <EmptySpace max="-2" attributes="0"/>
              <Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
              <EmptySpace pref="34" max="32767" attributes="0"/>
              <Component id="jButtonEnviar" min="-2" max="-2" attributes="0"/>
              <EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
          </Group>
      </Group>
    </DimensionLayout>
  </Layout>
  <SubComponents>
    <Component class="javax.swing.JButton" name="jButtonEnviar">
      <Properties>
        <Property name="text" type="java.lang.String" value="Enviar"/>
      </Properties>
      <Events>
        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" 
        parameters="java.awt.event.ActionEvent" handler="jButtonEnviarActionPerformed"/>
      </Events>
    </Component>
    <Component class="javax.swing.JLabel" name="jLabel1">
      <Properties>
        <Property name="text" type="java.lang.String" value="Assunto"/>
      </Properties>
    </Component>
    <Component class="javax.swing.JTextField" name="jTextFieldAssunto">
    </Component>
    <Component class="javax.swing.JLabel" name="jLabel2">
      <Properties>
        <Property name="text" type="java.lang.String" value="Email Destino"/>
      </Properties>
    </Component>
    <Component class="javax.swing.JTextField" name="jTextFieldEmailDestino">
    </Component>
    <Component class="javax.swing.JLabel" name="jLabel3">
      <Properties>
        <Property name="text" type="java.lang.String" value="Mensagem"/>
      </Properties>
    </Component>
    <Container class="javax.swing.JScrollPane" name="jScrollPane1">
      <AuxValues>
        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
      </AuxValues>
 
      <Layout ass="org.netbeans.modules.form.compat2
      .layouts.support.JScrollPaneSupportLayout"/>
      <SubComponents>
        <Component class="javax.swing.JTextArea" name="jTextAreaMensagem">
          <Properties>
            <Property name="columns" type="int" value="20"/>
            <Property name="rows" type="int" value="5"/>
          </Properties>
        </Component>
      </SubComponents>
    </Container>
  </SubComponents>
</Form>
Listagem 1. FmainMail.form

Antes de começarmos a construir o código do nosso formulário vamos primeiro construir os métodos responsáveis pelo envio do e-mail e explicar o funcionamento de cada um. Primeiramente o método mais interno, o criarSessionMail(), visto na Listagem 2.


private Session criarSessionMail() {
     Properties props = new Properties();

     props.put("mail.smtp.host", "smtp.gmail.com");
     props.put("mail.smtp.socketFactory.port", 465);
     props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
     props.put("mail.smtp.auth", true);
     props.put("mail.smtp.port", 465);

     Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {

            protected PasswordAuthentication getPasswordAuthentication() {
                   return new PasswordAuthentication("seuemail@gmail.com", "suasenha");
            }
     });

     session.setDebug(true);

     return session;
}
Listagem 2. criarSessionMail()

O método getDefaultInstance() da classe Session recebe dois parâmetros: um objeto Properties e um Authenticator. O Properties define as propriedades necessárias para conexão do servidor e-mail. Sendo assim, definimos o servidor SMPT com as configurações da Listagem 3.


Properties props = new Properties();

   props.put("mail.smtp.host", "smtp.gmail.com");
   props.put("mail.smtp.socketFactory.port", 465);
   props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
   props.put("mail.smtp.auth", true);
   props.put("mail.smtp.port", 465);
Listagem 3. Configurações do servidor SMPT

Estas configurações são específicas do GMAIL, mas você pode utilizar qualquer outro servidor de e-mail que

você tenha acesso aos dados do SMTP. A classe Authenticator é abstrata, então fazemos uma

instanciação anônima para não precisar armazenar a referência do objeto:


Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {

    protected PasswordAuthentication getPasswordAuthentication() {
           return new PasswordAuthentication("seuemail@gmail.com", "suasenha");
    }
});

Perceba que no código passamos dois parâmetros de extrema importância: o e-mail de autenticação e a senha.

Por fim, configuramos o objeto Session em modo “debug” para que ele mostre o que está acontecendo ao enviar o e-mail. O mesmo é retornado para a função que fez a chamada. Esse método é o responsável por realizar toda a conexão com o servidor SMTP: é apenas neste ponto que configuraremos os dados de autenticação, portas e endereços de conexão. Veremos na Listagem 3 a configuração para envio do e-mail propriamente dito, tais como assunto, mensagem, destinatário e etc.


private void enviarEmail() throws AddressException, MessagingException {
     
     String msg = jTextAreaMensagem.getText();
     String assunto = jTextFieldAssunto.getText();
     String email = jTextFieldEmailDestino.getText();
     
     String remetente = "remetente@gmail.com";
     System.out.println("__________________________________________________");
     System.out.println("Enviando email DE: " + remetente + " PARA: " + email);
     System.out.println("Assunto: " + assunto);

     Message message = new MimeMessage(criarSessionMail());
     message.setFrom(new InternetAddress(remetente)); // Remetente

     Address[] toUser = InternetAddress // Destinatário(s)
                   .parse(email.trim().toLowerCase());

     message.setRecipients(Message.RecipientType.TO, toUser);
     message.setSubject(assunto);// Assunto
     message.setContent(msg, "text/html");
     /** Método para enviar a mensagem criada */
     Transport.send(message);

     System.out.println("Email enviado com sucesso !");
     System.out.println("__________________________________________________");

}
Listagem 3. enviarEmail()

As três primeiras variáveis são dinâmicas, preenchidas pelo usuário:


String msg = jTextAreaMensagem.getText();
 String assunto = jTextFieldAssunto.getText();
       String email = jTextFieldEmailDestino.getText();

O remetente é o e-mail que o destinatário verá, ou seja, você pode autenticar com um e-mail abc@gmail.com e colocar o remetente como outroemail@gmail.com. A classe Message é abstrata então precisamos implementá-la. Para isso usamos o MimeMessage que obrigatoriamente deve receber um Session em seu construtor. Sendo assim usamos o método criado anteriormente criarSessionMail() para retornar um Session e passar ao MimeMessage:


Message message = new MimeMessage(criarSessionMail());

Com uma instância de Message em mãos nós podemos começar a configurar nosso e-mail, ou seja, os dados de envio.

O primeiro parâmetro é o remetente e usamos o setFrom() para defini-lo:


message.setFrom(new InternetAddress(remetente)); // Remetente

O método setFrom() recebe um objeto do tipo InternetAddress, sendo assim, criamos este objeto passando para o seu construtor o endereço do remetente.

O método setRecipients() recebe a forma de vinculação dos destinatários ao e-mail. Por exemplo: quatro e-mails podem ser destinatário ocultos, sendo assim configuraríamos como RecipientType.CC, mas como em nosso caso o único e-mail será o principal usamos o RecipientType.TO:


message.setRecipients(Message.RecipientType.TO, toUser);

O objeto toUser é um array de Address que criamos anteriormente através do método InternetAddress.parse():


Address[] toUser = InternetAddress // Destinatário(s)
 .parse(email.trim().toLowerCase());

Podemos passar vários e-mails ao parse() e não apenas um como é nosso caso.

O próximo passo é configurar o assunto e o conteúdo do e-mail:


message.setSubject(assunto);// Assunto
     message.setContent(msg, "text/html");

Configuramos o conteúdo do e-mail como “text/html”, pois será apenas texto puro, sem vídeos ou outras características especiais. Por fim usamos a classe Transport para enviar o e-mail através do método send():


Transport.send(message);

Se tudo der certo a mensagem Email Enviado com Sucesso será mostrada no console, caso contrário, uma exceção pode ser lançada, sendo ela: AddressException ou MessagingException. Em nosso caso não estamos tratando esse tipo de exceção, apenas lançando “para cima”, mas você pode ficar à vontade para tratar e mostrar uma mensagem específica para o usuário, tal como: Impossível enviar este e-mail, tente novamente mais tarde ou verifique as configurações de envio.

Agora vejamos a criação dos nossos componentes dentro do formulário, como mostra a Listagem 4.


private javax.swing.JButton jButtonEnviar;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea jTextAreaMensagem;
private javax.swing.JTextField jTextFieldAssunto;
private javax.swing.JTextField jTextFieldEmailDestino;


private void initComponents() {


     jButtonEnviar = new javax.swing.JButton();
     jLabel1 = new javax.swing.JLabel();
     jTextFieldAssunto = new javax.swing.JTextField();
     jLabel2 = new javax.swing.JLabel();
     jTextFieldEmailDestino = new javax.swing.JTextField();
     jLabel3 = new javax.swing.JLabel();
     jScrollPane1 = new javax.swing.JScrollPane();
     jTextAreaMensagem = new javax.swing.JTextArea();


     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);


     jButtonEnviar.setText("Enviar");
     jButtonEnviar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                   jButtonEnviarActionPerformed(evt);
            }
     });


     jLabel1.setText("Assunto");


     jLabel2.setText("Email Destino");


     jLabel3.setText("Mensagem");


     jTextAreaMensagem.setColumns(20);
     jTextAreaMensagem.setRows(5);
     jScrollPane1.setViewportView(jTextAreaMensagem);


     javax.swing.GroupLayout layout = 
     new javax.swing.GroupLayout(getContentPane());
     getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING).addGroup(
 layout.createSequentialGroup()
    .addContainerGap()
    .addGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
           .addComponent(jScrollPane1)
           .addGroup(
               layout.createSequentialGroup()
                  .addGroup(
                      layout.createParallelGroup(
                      javax.swing.GroupLayout.Alignment.LEADING).addComponent(
                      jButtonEnviar).addComponent(jLabel1);
layout.setVerticalGroup(layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING).addGroup(
 javax.swing.GroupLayout.Alignment.TRAILING,
 layout.createSequentialGroup().addGap(21, 21, 21).addComponent(jLabel1)
 .addPreferredGap(
 javax.swing.LayoutStyle.ComponentPlacement.RELATED)
    .addComponent(jTextFieldAssunto, javax.swing.GroupLayout.PREFERRED_SIZE, 
    javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
    .addGap(18, 18, 
    18)
     .addComponent(jLabel2).addPreferredGap(javax.swing.LayoutStyle
     .ComponentPlacement.RELATED)
    .addComponent(jTextFieldEmailDestino, javax.swing.GroupLayout.PREFERRED_SIZE, 
    javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
    .addGap(18, 18, 
    18)
     .addComponent(jLabel3).addPreferredGap(javax.swing.LayoutStyle
     .ComponentPlacement.RELATED)
    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 
    javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout
    .PREFERRED_SIZE)
     .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 34, 
     Short.MAX_VALUE).addComponent(jButtonEnviar).addGap(21, 21, 21)));


     pack();
}
Listagem 4. Inicializando componentes do formulário

O código apresentado, pertencente ao método initcomponents(), é responsável por inicializar todo layout e componentes gráficos no formulário. Você pode colocar ele dentro do construtor da classe. O que nos importa neste caso é o botão jButtonEnviar, que possui um listener que é disparado quando o click do botão é efetuado, o método jButtonEnviarActionPerformed() é chamado, como mostra a Listagem 5.


private void jButtonEnviarActionPerformed(java.awt.event.ActionEvent evt) {
// GEN-FIRST:event_jButtonEnviarActionPerformed
     try {
            enviarEmail();
     } catch (AddressException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
     } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
     }
}// GEN-LAST:event_jButtonEnviarActionPerformed
Listagem 5. jButtonEnviarActionPerformed

A única função deste método é chamar o método enviarEmail() que já explicamos anteriormente em detalhes. Lembre-se que falamos que nossas exceções (AddressException e MessagingException) foram lançadas para cima, e é neste método que tratamos ela.

Neste artigo demonstramos como realizar a configuração necessária para enviar e-mail em Java. Trabalhamos coma configurações SMTP para o gmail mas você poderá usar outro servidor se achar conveniente.

Todo nosso projeto foi baseado no pacote javax.mail principalmente com as classes Session, Transport e Message. Aplicamos este a um formulário para demonstrar como utilizá-lo, mas você pode ir muito além e acoplar tão funcionalidade a um Helper que pode ser usado em qualquer ponto do sistema, abstraindo a complexidade necessária para envio de e-mail. Outra questão importante são as configurações do servidor SMTP, pois neste artigo configuramos manualmente via código, mas o ideal é fazer isso de forma dinâmica, seja através do banco de dados ou através de um arquivo.