Introdução
Além da necessidade de envio de e-mail ser comum a várias aplicações, foi a pergunta de um aluno da Academia Java,“Como enviar um e-mail com Java?”, que me motivou a escrever este post sobre JavaMail.
JavaMail
Para realizar o envio de e-mail por meio de uma aplicação Java, precisamos da biblioteca JavaMail, pois ela não é incluída no Java SE. A biblioteca está disponível em http://www.oracle.com/technetwork/java/index-138643.html.
Neste download, além da biblioteca
A forma mais simples de utilizar a JavaMail e incluir o
Exemplo
Como o objetivo é realizar o envio de e-mail, precisamos configurar o servidor de envio (SMTP), para tanto vamos criar um objeto
Além da necessidade de envio de e-mail ser comum a várias aplicações, foi a pergunta de um aluno da Academia Java,
JavaMail
Para realizar o envio de e-mail por meio de uma aplicação Java, precisamos da biblioteca JavaMail, pois ela não é incluída no Java SE. A biblioteca está disponível em http://www.oracle.com/technetwork/java/index-138643.html.
Neste download, além da biblioteca
mail.jar
que inclui a implementação completa da API e providers, também é disponibilizada a documentação da biblioteca (javadoc
) na pasta docs
, alguns exemplos na pasta demo
e partes da implementação em lib
.A forma mais simples de utilizar a JavaMail e incluir o
mail.jar
, porém para uma aplicação que só envia e-mail como o nosso exemplo, necessitamos apenas dos arquivos mailapi.jar
e smtp.jar
, economizando 177KB. Como a economia é pouca e as aplicações evoluem, vamos adicionar o mail.jar
no classpath da aplicação.Exemplo
Como o objetivo é realizar o envio de e-mail, precisamos configurar o servidor de envio (SMTP), para tanto vamos criar um objeto
java.util.Properties
, e adicionar a propriedade "mail.host"
com o servidor que será utilizado para envio://o valor "smtp.host.com.br" deve ser alterado para o seu servidor SMTP props.put("mail.host","smtp.host.com.br");Para ter acesso ao provider de envio de email, vamos obter um objeto
javax.mail.Session
, por meio do método estático getDefaultInstance
passando o objeto props
com a configuração do servidor SMTP:Session session = Session.getDefaultInstance(props);Agora vamos criar uma mensagem
javax.mail.internet.MimeMessage
vazia, com o construtor que recebe um objeto do tipo javax.mail.Session
:MimeMessage message = new MimeMessage(session);Para configurar os endereços de remetente (
from
) e de destinatário (to
) da mensagem, vamos criar dois objetos javax.mail.internet.InternetAddress
e configurar o objeto message
, conforme segue:Address from = new InternetAddress("remetente@host.com"); Address to = new InternetAddress("destinatario@host.com"); message.setFrom(from); message.addRecipient(RecipientType.TO, to);Para configurar o endereço do remetente da mensagem, utilizamos o método
setFrom
e para configurar o destinatário utilizamos o método addRecipient
, que pode ser chamado diversas vezes para encaminhar a mensagem para vários destinatários, este método recebe, além do endereço (segundo parâmetro), o primeiro parâmetro com um RecipientType
, para configurar o destinatário “para” utilizamos o RecipientType.TO
, “com cópia” e “com cópia oculta” utilizamos RecipientType.CC
e RecipientType.BCC
respectivamente.Então realizar a configuração da data de envio, por meio do método
Agora que a mensagem esta pronta, vamos utilizar enviar utilizando o método estático
Segue o código completo da classe que envia um e-mail.
Afinal, você gosta de SPAM? ... nem EU! J
Até mais!
Marcelo de Castro
http://blog.castro.eti.br
http://twitter.com/mcastroinfo
http://www.globalcode.com.br/instrutores/MarceloCastro
Outros posts: http://blog.globalcode.com.br/search/label/MarceloCastro
setSentDate
, do assunto, por meio do método setSubject
e do texto da mensagem, setText
conforme segue:message.setSentDate(new Date()); message.setSubject("Assunto da mensagem"); message.setText("Texto da mensagem");O método
setSentDate
configura o cabeçalho “Date” da mensagem, se a data não for configurada, o referido cabeçalho não será enviado.Agora que a mensagem esta pronta, vamos utilizar enviar utilizando o método estático
send
da classe javax.mail.Transport
:Transport.send(message);MailSender.java
Segue o código completo da classe que envia um e-mail.
package br.eti.castro.blog.samples.email; //imports omitidos public class MailSender { //o tratamento de excessoes foi simplificado (throws AddressException, MessagingException) //para facilitar o entendimento do exemplo public static void main(String[] args) throws AddressException, MessagingException { //objeto para definicao das propriedades de configuracao do provider Properties props = new Properties(); //o valor "smtp.host.com.br" deve ser alterado para o seu servidor SMTP props.put("mail.host","smtp.host.com.br"); //obtendo um Session com a configuração //do servidor SMTP definida em props Session session = Session.getDefaultInstance(props); //criando a mensagem MimeMessage message = new MimeMessage(session); //substituir pelos e-mails desejados Address from = new InternetAddress("remetente@host.com"); Address to = new InternetAddress("destinatario@host.com"); //configurando o remetente e o destinatario message.setFrom(from); message.addRecipient(RecipientType.TO, to); //configurando a data de envio, o assunto e o texto da mensagem message.setSentDate(new Date()); message.setSubject("Assunto da mensagem"); message.setText("Texto da mensagem!"); //enviando Transport.send(message); } }Isso é o que você precisa para enviar uma mensagem com Java, porém é necessário cuidado com a utilização deste código em laços de repetição, ou seja, enviar uma grande quantidade de mensagens em um curto de período de tempo, pois seu endereço, domínio ou IP podem cair em uma balcklist, e seus e-mails serem classificados como SPAM.
Afinal, você gosta de SPAM? ... nem EU! J
Até mais!
Marcelo de Castro
http://blog.castro.eti.br
http://twitter.com/mcastroinfo
http://www.globalcode.com.br/instrutores/MarceloCastro
Outros posts: http://blog.globalcode.com.br/search/label/MarceloCastro
Comentários
Entretanto o segunte erro apareceu:
"java.lang.NoClassDefFoundError : javax/mail/Address"
Meu manifest, classpath esta tudo certo!
ja teve esse erro?
Só que eu também não sei qual é?
Alguém sabe qual é?
Apesar de você dizer que seu classpath está correto, mas devido ao erro apresentado, acredito que você compilou com o classpath configurado corretamente, porém na execução a biblioteca mail.jar (onde encontramos a classe javax.mail.Address e outras utilizadas) não está devidamente configurada no classpath.
Exemplos:
Compilando
javac -cp caminhoDoJar/mail.jar;. br/eti/castro/blog/samples/email/MailSender.java
Executando
java -cp caminhoDoJar/mail.jar;. br.eti.castro.blog.samples.email.MailSender
Espero que ajude
Qualquer dúvida estou a disposição
Marcelo de Castro
É isso mesmo, na hora da execução a classe javax.mail.Adress não foi encontrada por não estar no classpath. Esta classe e outras que utilizamos estão na biblioteca mail.jar.
Abraços
DEBUG: setDebug: JavaMail version 1.5.3
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
Exception in thread "main" java.lang.RuntimeException: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.gmail.com, 587; timeout -1;
nested exception is:
java.net.SocketException: Permission denied: connect
at projekt.JavaMail.main(JavaMail.java:55)
Caused by: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.gmail.com, 587; timeout -1;
nested exception is:
java.net.SocketException: Permission denied: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2054)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:697)
at javax.mail.Service.connect(Service.java:386)
at javax.mail.Service.connect(Service.java:245)
at javax.mail.Service.connect(Service.java:194)
at javax.mail.Transport.send0(Transport.java:253)
at javax.mail.Transport.send(Transport.java:124)
at projekt.JavaMail.main(JavaMail.java:50)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:329)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:236)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2020)
... 7 more
Java Result: 1
Peguei um código de outra página e as informações batem com aqui.
Por estar dentro da rede da minha empresa, eu add o endereço de proxy(não o ip, o endereço) e a porta mas não conecta.
Penso que seja devido ao firewall correto???
O problema está na autenticação com o servidor smtp do Gmail:
java.net.SocketException: Permission denied: connect
Segue um trecho com o uso de Authenticator:
private Session getGmailSession() {
Authenticator authenticator = new Authenticator();
Properties properties = new Properties();
properties.setProperty("mail.smtp.submitter", authenticator
.getPasswordAuthentication().getUserName());
properties.setProperty("mail.smtp.auth", "true");
properties.setProperty("mail.smtp.host", type.mailHost);
properties.setProperty("mail.smtp.port", type.port);
properties.put("mail.smtp.socketFactory.port", type.port);
properties.put("mail.smtp.socketFactory.class", SSL_FACTORY);
properties.put("mail.smtp.socketFactory.fallback", "false");
return Session.getInstance(properties, authenticator);
}
private class Authenticator extends javax.mail.Authenticator {
private PasswordAuthentication authentication;
public Authenticator() {
authentication = new PasswordAuthentication(type.username, type.password);
}
protected PasswordAuthentication getPasswordAuthentication() {
return authentication;
}
}