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.
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>
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;
}
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);
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("__________________________________________________");
}
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();
}
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
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.