Como posso enviar um email por aplicativo Java usando GMail, Yahoo ou Hotmail?

206

É possível enviar um email do meu aplicativo Java usando uma conta do GMail? Eu configurei o servidor de correio da empresa com o aplicativo Java para enviar email, mas isso não será suficiente quando eu distribuir o aplicativo. Respostas com o uso do Hotmail, Yahoo ou GMail são aceitáveis.

Bill the Lizard
fonte

Respostas:

190

Primeiro faça o download da API JavaMail e verifique se os arquivos jar relevantes estão no seu caminho de classe.

Aqui está um exemplo completo de trabalho usando o GMail.

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

public class Main {

    private static String USER_NAME = "*****";  // GMail user name (just the part before "@gmail.com")
    private static String PASSWORD = "********"; // GMail password
    private static String RECIPIENT = "[email protected]";

    public static void main(String[] args) {
        String from = USER_NAME;
        String pass = PASSWORD;
        String[] to = { RECIPIENT }; // list of recipient email addresses
        String subject = "Java send mail example";
        String body = "Welcome to JavaMail!";

        sendFromGMail(from, pass, to, subject, body);
    }

    private static void sendFromGMail(String from, String pass, String[] to, String subject, String body) {
        Properties props = System.getProperties();
        String host = "smtp.gmail.com";
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.user", from);
        props.put("mail.smtp.password", pass);
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.auth", "true");

        Session session = Session.getDefaultInstance(props);
        MimeMessage message = new MimeMessage(session);

        try {
            message.setFrom(new InternetAddress(from));
            InternetAddress[] toAddress = new InternetAddress[to.length];

            // To get the array of addresses
            for( int i = 0; i < to.length; i++ ) {
                toAddress[i] = new InternetAddress(to[i]);
            }

            for( int i = 0; i < toAddress.length; i++) {
                message.addRecipient(Message.RecipientType.TO, toAddress[i]);
            }

            message.setSubject(subject);
            message.setText(body);
            Transport transport = session.getTransport("smtp");
            transport.connect(host, from, pass);
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
        }
        catch (AddressException ae) {
            ae.printStackTrace();
        }
        catch (MessagingException me) {
            me.printStackTrace();
        }
    }
}

Naturalmente, você desejará fazer mais nos catchblocos do que imprimir o rastreamento de pilha, como fiz no código de exemplo acima. (Remova os catchblocos para ver quais chamadas de método da API JavaMail lançam exceções para que você possa ver melhor como tratá-las adequadamente.)


Obrigado a @jodonnel e a todos os outros que responderam. Estou lhe dando uma recompensa porque sua resposta me levou cerca de 95% do caminho para uma resposta completa.

Bill the Lizard
fonte
1
@varun: Essa é a porta no servidor de email de saída smtp.gmail.com,. Consulte Configurando outros clientes de email para obter detalhes.
Bill o Lagarto
1
Eu sou o único que obtém o AuthenticationFailedException aqui props.put ("mail.smtp.auth", "true"); se o verdadeiro for string. Tudo bem se for um booleano.
nyxz
2
Para conexão SSL do gmail, use props.put ("mail.smtp.port", "465"); // em vez de 587
Tomasz Dziurko
2
Consulte oracle.com/technetwork/java/faq-135477.html#getdefaultinstance sobre o uso de Session.getDefaultInstance (properties). Esta FAQ recomenda o uso de getInstance (..).
Bryan
7
Não consegui acessar usando o SMTP gmail com os códigos acima e similares e estava obtendo javax.mail.AuthenticationFailedExceptione tive que ativar explicitamente "aplicativos menos seguros" nas minhas configurações do gmail: google.com/settings/security/lesssecureapps . Uma vez que os "aplicativos menos seguros" foram ativados, o código funcionou
Marcus Junius Brutus
110

Algo assim (parece que você só precisa alterar o servidor SMTP):

String host = "smtp.gmail.com";
String from = "user name";
Properties props = System.getProperties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", from);
props.put("mail.smtp.password", "asdfgh");
props.put("mail.smtp.port", "587"); // 587 is the port number of yahoo mail
props.put("mail.smtp.auth", "true");

Session session = Session.getDefaultInstance(props, null);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));

InternetAddress[] to_address = new InternetAddress[to.length];
int i = 0;
// To get the array of addresses
while (to[i] != null) {
    to_address[i] = new InternetAddress(to[i]);
    i++;
}
System.out.println(Message.RecipientType.TO);
i = 0;
while (to_address[i] != null) {

    message.addRecipient(Message.RecipientType.TO, to_address[i]);
    i++;
}
message.setSubject("sending in a group");
message.setText("Welcome to JavaMail");
// alternately, to send HTML mail:
// message.setContent("<p>Welcome to JavaMail</p>", "text/html");
Transport transport = session.getTransport("smtp");
transport.connect("smtp.mail.yahoo.co.in", "user name", "asdfgh");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
jodonnell
fonte
É possível enviar o conteúdo como html? Se eu tentar escrever um código html e enviá-lo, mas no final do recebimento, o conteúdo do e-mail é apenas código html.
Thang Pham
4
Para enviar corpo html em vez de texto não criptografado, altere esta linha: message.setText("Welcome to JavaMail");com esta linha:message.setContent("<h1>Hello world</h1>", "text/html");
mist
4
Este está faltando ("mail.smtp.starttls.enable", "true")
Sotomajor, 03/10/12
não há necessidade de importar alguma biblioteca javal? e @Sotomajor, onde usamos essa linha que falta?
Gmuruh
@gumuruh nos adereços. Deveria ter sidoprops.put("mail.smtp.starttls.enable", "true")
Sotomajor
21

Outras pessoas têm boas respostas acima, mas eu gostaria de adicionar uma nota sobre minha experiência aqui. Descobri que, ao usar o Gmail como um servidor SMTP de saída para meu aplicativo da web, o Gmail só permite enviar ~ 10 mensagens antes de responder com uma resposta antispam que eu preciso seguir manualmente para reativar o acesso SMTP. Os emails que eu estava enviando não eram spam, mas eram emails de "bem-vindo" do site quando os usuários se registraram no meu sistema. Então, YMMV, e eu não confiaria no Gmail para um webapp de produção. Se você estiver enviando email em nome de um usuário, como um aplicativo de desktop instalado (onde o usuário insere suas próprias credenciais do Gmail), você pode ficar bem.

Além disso, se você estiver usando o Spring, aqui está uma configuração funcional para usar o Gmail para SMTP de saída:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="host" value="smtp.gmail.com"/>
    <property name="port" value="465"/>
    <property name="username" value="${mail.username}"/>
    <property name="password" value="${mail.password}"/>
    <property name="javaMailProperties">
        <value>
            mail.debug=true
            mail.smtp.auth=true
            mail.smtp.socketFactory.class=java.net.SocketFactory
            mail.smtp.socketFactory.fallback=false
        </value>
    </property>
</bean>
Jason Thrasher
fonte
Obrigado Jason, pelo exemplo das definições de configuração e pelo aviso sobre os limites de correio de saída. Nunca cheguei ao limite antes, mas tenho certeza que outras pessoas acharão essas informações úteis.
Bill o Lagarto
Gostaria de saber mais sobre esse limite de spam ... Preciso enviar vários emails, devo dividi-los em grupos? aguarde um período de tempo especificado? Alguém sabe os detalhes das limitações do Google Mail?
opensas 11/04/10
12

Embora essa pergunta esteja encerrada, eu gostaria de postar uma solução de contador, mas agora usando o Simple Java Mail (invólucro smtp de código aberto JavaMail):

final Email email = new Email();

String host = "smtp.gmail.com";
Integer port = 587;
String from = "username";
String pass = "password";
String[] to = {"[email protected]"};

email.setFromAddress("", from);
email.setSubject("sending in a group");
for( int i=0; i < to.length; i++ ) {
    email.addRecipient("", to[i], RecipientType.TO);
}
email.setText("Welcome to JavaMail");

new Mailer(host, port, from, pass).sendMail(email);
// you could also still use your mail session instead
new Mailer(session).sendMail(email);
user109771
fonte
2
Estou recebendo um erro com esse código: "Mensagem: Erro genérico: 530 5.7.0 É necessário emitir um comando STARTTLS primeiro" - como você habilita o starttls com o vesijama?
Iddqd 20/03/11
1
Eu recebi o erro "É necessário emitir um comando STARTTLS primeiro" porque na linha abaixo eu tinha a variável isStartTlsEnabled como um booleano, em vez disso como uma String: props.put ("mail.smtp.starttls.enable", isStartTlsEnabled);
user64141
Desde esta resposta : Para usar TLS, você pode fazer algo comonew Mailer(your login / your session, TransportStrategy.SMTP_TLS).sendMail(email);
Benny Bottema
7

Meu código completo, como abaixo, está funcionando bem:

package ripon.java.mail;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

public class SendEmail
{
public static void main(String [] args)
{    
    // Sender's email ID needs to be mentioned
     String from = "[email protected]";
     String pass ="test123";
    // Recipient's email ID needs to be mentioned.
   String to = "[email protected]";

   String host = "smtp.gmail.com";

   // Get system properties
   Properties properties = System.getProperties();
   // Setup mail server
   properties.put("mail.smtp.starttls.enable", "true");
   properties.put("mail.smtp.host", host);
   properties.put("mail.smtp.user", from);
   properties.put("mail.smtp.password", pass);
   properties.put("mail.smtp.port", "587");
   properties.put("mail.smtp.auth", "true");

   // Get the default Session object.
   Session session = Session.getDefaultInstance(properties);

   try{
      // Create a default MimeMessage object.
      MimeMessage message = new MimeMessage(session);

      // Set From: header field of the header.
      message.setFrom(new InternetAddress(from));

      // Set To: header field of the header.
      message.addRecipient(Message.RecipientType.TO,
                               new InternetAddress(to));

      // Set Subject: header field
      message.setSubject("This is the Subject Line!");

      // Now set the actual message
      message.setText("This is actual message");

      // Send message
      Transport transport = session.getTransport("smtp");
      transport.connect(host, from, pass);
      transport.sendMessage(message, message.getAllRecipients());
      transport.close();
      System.out.println("Sent message successfully....");
   }catch (MessagingException mex) {
      mex.printStackTrace();
   }
}
}
Ripon Al Wasim
fonte
3
//set CLASSPATH=%CLASSPATH%;activation.jar;mail.jar
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public class Mail
{
    String  d_email = "[email protected]",
            d_password = "****",
            d_host = "smtp.gmail.com",
            d_port  = "465",
            m_to = "[email protected]",
            m_subject = "Testing",
            m_text = "Hey, this is the testing email using smtp.gmail.com.";
    public static void main(String[] args)
    {
        String[] to={"[email protected]"};
        String[] cc={"[email protected]"};
        String[] bcc={"[email protected]"};
        //This is for google
        Mail.sendMail("[email protected]", "password", "smtp.gmail.com", 
                      "465", "true", "true", 
                      true, "javax.net.ssl.SSLSocketFactory", "false", 
                      to, cc, bcc, 
                      "hi baba don't send virus mails..", 
                      "This is my style...of reply..If u send virus mails..");
    }

    public synchronized static boolean sendMail(
        String userName, String passWord, String host, 
        String port, String starttls, String auth, 
        boolean debug, String socketFactoryClass, String fallback, 
        String[] to, String[] cc, String[] bcc, 
        String subject, String text) 
    {
        Properties props = new Properties();
        //Properties props=System.getProperties();
        props.put("mail.smtp.user", userName);
        props.put("mail.smtp.host", host);
        if(!"".equals(port))
            props.put("mail.smtp.port", port);
        if(!"".equals(starttls))
            props.put("mail.smtp.starttls.enable",starttls);
        props.put("mail.smtp.auth", auth);
        if(debug) {
            props.put("mail.smtp.debug", "true");
        } else {
            props.put("mail.smtp.debug", "false");         
        }
        if(!"".equals(port))
            props.put("mail.smtp.socketFactory.port", port);
        if(!"".equals(socketFactoryClass))
            props.put("mail.smtp.socketFactory.class",socketFactoryClass);
        if(!"".equals(fallback))
            props.put("mail.smtp.socketFactory.fallback", fallback);

        try
        {
            Session session = Session.getDefaultInstance(props, null);
            session.setDebug(debug);
            MimeMessage msg = new MimeMessage(session);
            msg.setText(text);
            msg.setSubject(subject);
            msg.setFrom(new InternetAddress("[email protected]"));
            for(int i=0;i<to.length;i++) {
                msg.addRecipient(Message.RecipientType.TO, 
                                 new InternetAddress(to[i]));
            }
            for(int i=0;i<cc.length;i++) {
                msg.addRecipient(Message.RecipientType.CC, 
                                 new InternetAddress(cc[i]));
            }
            for(int i=0;i<bcc.length;i++) {
                msg.addRecipient(Message.RecipientType.BCC, 
                                 new InternetAddress(bcc[i]));
            }
            msg.saveChanges();
            Transport transport = session.getTransport("smtp");
            transport.connect(host, userName, passWord);
            transport.sendMessage(msg, msg.getAllRecipients());
            transport.close();
            return true;
        }
        catch (Exception mex)
        {
            mex.printStackTrace();
            return false;
        }
    }

}
vishnu
fonte
3

O mínimo necessário:

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MessageSender {

    public static void sendHardCoded() throws AddressException, MessagingException {
        String to = "[email protected]";
        final String from = "[email protected]";

        Properties properties = new Properties();
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.host", "smtp.gmail.com");
        properties.put("mail.smtp.port", "587");

        Session session = Session.getInstance(properties,
                new javax.mail.Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(from, "BeNice");
                    }
                });

        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
        message.setSubject("Hello");
        message.setText("What's up?");

        Transport.send(message);
    }

}
AlikElzin-kilaka
fonte
1
@ AlikElizin-kilaka Eu estava tentando usar meu ID do Gmail para remetente e destinatário, e descobri que você também precisa definir o sinalizador Permitir aplicativos menos seguros como LIGADO nas configurações da sua conta do Google, pois você está acessando seu perfil do Gmail de uma forma menos segura maneira. Somente você poderá ver o email enviado do cliente Java. Caso contrário, você obtém o javax.mail.AuthenticationFailedException.
kunal
2

As soluções de código postado podem causar problemas quando você precisar configurar várias sessões SMTP em qualquer lugar da mesma JVM.

O FAQ do JavaMail recomenda o uso de

Session.getInstance(properties);

ao invés de

Session.getDefaultInstance(properties);

porque o getDefault usará apenas as propriedades fornecidas na primeira vez que for invocado. Todos os usos posteriores da instância padrão ignoram as alterações de propriedade.

Consulte http://www.oracle.com/technetwork/java/faq-135477.html#getdefaultinstance

Bryan
fonte
1

É isso que faço quando quero enviar um email com anexo, funciona bem. :)

 public class NewClass {

    public static void main(String[] args) {
        try {
            Properties props = System.getProperties();
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.host", "smtp.gmail.com");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.port", "465"); // smtp port
            Authenticator auth = new Authenticator() {

                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("username-gmail", "password-gmail");
                }
            };
            Session session = Session.getDefaultInstance(props, auth);
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress("[email protected]"));
            msg.setSubject("Try attachment gmail");
            msg.setRecipient(RecipientType.TO, new InternetAddress("[email protected]"));
            //add atleast simple body
            MimeBodyPart body = new MimeBodyPart();
            body.setText("Try attachment");
            //do attachment
            MimeBodyPart attachMent = new MimeBodyPart();
            FileDataSource dataSource = new FileDataSource(new File("file-sent.txt"));
            attachMent.setDataHandler(new DataHandler(dataSource));
            attachMent.setFileName("file-sent.txt");
            attachMent.setDisposition(MimeBodyPart.ATTACHMENT);
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(body);
            multipart.addBodyPart(attachMent);
            msg.setContent(multipart);
            Transport.send(msg);
        } catch (AddressException ex) {
            Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MessagingException ex) {
            Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
Ifnu
fonte
0

Uma rota fácil seria ter a conta do Gmail configurada / ativada para acesso POP3. Isso permitiria enviar via SMTP normal através dos servidores do Gmail.

Em seguida, basta enviar smtp.gmail.com (na porta 587)

Ryan Farley
fonte
0

Oi tente este código ....

package my.test.service;

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Message;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class Sample {
    public static void main(String args[]) {
        final String SMTP_HOST = "smtp.gmail.com";
        final String SMTP_PORT = "587";
        final String GMAIL_USERNAME = "[email protected]";
        final String GMAIL_PASSWORD = "xxxxxxxxxx";

        System.out.println("Process Started");

        Properties prop = System.getProperties();
        prop.setProperty("mail.smtp.starttls.enable", "true");
        prop.setProperty("mail.smtp.host", SMTP_HOST);
        prop.setProperty("mail.smtp.user", GMAIL_USERNAME);
        prop.setProperty("mail.smtp.password", GMAIL_PASSWORD);
        prop.setProperty("mail.smtp.port", SMTP_PORT);
        prop.setProperty("mail.smtp.auth", "true");
        System.out.println("Props : " + prop);

        Session session = Session.getInstance(prop, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(GMAIL_USERNAME,
                        GMAIL_PASSWORD);
            }
        });

        System.out.println("Got Session : " + session);

        MimeMessage message = new MimeMessage(session);
        try {
            System.out.println("before sending");
            message.setFrom(new InternetAddress(GMAIL_USERNAME));
            message.addRecipients(Message.RecipientType.TO,
                    InternetAddress.parse(GMAIL_USERNAME));
            message.setSubject("My First Email Attempt from Java");
            message.setText("Hi, This mail came from Java Application.");
            message.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse(GMAIL_USERNAME));
            Transport transport = session.getTransport("smtp");
            System.out.println("Got Transport" + transport);
            transport.connect(SMTP_HOST, GMAIL_USERNAME, GMAIL_PASSWORD);
            transport.sendMessage(message, message.getAllRecipients());
            System.out.println("message Object : " + message);
            System.out.println("Email Sent Successfully");
        } catch (AddressException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Pyare
fonte
0

Aqui está uma aula fácil de usar para o envio de e-mails Gmail. Você precisa adicionar a JavaMailbiblioteca ao seu caminho de compilação ou apenas usar Maven.

import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class GmailSender
{
    private static String protocol = "smtp";

    private String username;
    private String password;

    private Session session;
    private Message message;
    private Multipart multipart;

    public GmailSender()
    {
        this.multipart = new MimeMultipart();
    }

    public void setSender(String username, String password)
    {
        this.username = username;
        this.password = password;

        this.session = getSession();
        this.message = new MimeMessage(session);
    }

    public void addRecipient(String recipient) throws AddressException, MessagingException
    {
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipient));
    }

    public void setSubject(String subject) throws MessagingException
    {
        message.setSubject(subject);
    }

    public void setBody(String body) throws MessagingException
    {
        BodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setText(body);
        multipart.addBodyPart(messageBodyPart);

        message.setContent(multipart);
    }

    public void send() throws MessagingException
    {
        Transport transport = session.getTransport(protocol);
        transport.connect(username, password);
        transport.sendMessage(message, message.getAllRecipients());

        transport.close();
    }

    public void addAttachment(String filePath) throws MessagingException
    {
        BodyPart messageBodyPart = getFileBodyPart(filePath);
        multipart.addBodyPart(messageBodyPart);

        message.setContent(multipart);
    }

    private BodyPart getFileBodyPart(String filePath) throws MessagingException
    {
        BodyPart messageBodyPart = new MimeBodyPart();
        DataSource dataSource = new FileDataSource(filePath);
        messageBodyPart.setDataHandler(new DataHandler(dataSource));
        messageBodyPart.setFileName(filePath);

        return messageBodyPart;
    }

    private Session getSession()
    {
        Properties properties = getMailServerProperties();
        Session session = Session.getDefaultInstance(properties);

        return session;
    }

    private Properties getMailServerProperties()
    {
        Properties properties = System.getProperties();
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.host", protocol + ".gmail.com");
        properties.put("mail.smtp.user", username);
        properties.put("mail.smtp.password", password);
        properties.put("mail.smtp.port", "587");
        properties.put("mail.smtp.auth", "true");

        return properties;
    }
}

Exemplo de uso:

GmailSender sender = new GmailSender();
sender.setSender("[email protected]", "mypassword");
sender.addRecipient("[email protected]");
sender.setSubject("The subject");
sender.setBody("The body");
sender.addAttachment("TestFile.txt");
sender.send();
BullyWiiPlaza
fonte
0

Se você deseja usar o Outlook Javamail API, use

smtp-mail.outlook.com

como host para obter mais e código de trabalho completo Confira esta resposta .

Inzimam Tariq IT
fonte
0

Valor adicionado:

  • codificando armadilhas no assunto, mensagem e nome de exibição
  • apenas uma propriedade mágica é necessária para as versões modernas da biblioteca de correio java
  • Session.getInstance() recomendado sobre Session.getDefaultInstance()
  • anexo no mesmo exemplo
  • ainda funciona depois que o Google desativa aplicativos menos seguros : ative a autenticação de dois fatores em sua organização -> ative 2FA -> gere a senha do aplicativo.
    import java.io.File;
    import java.nio.charset.StandardCharsets;
    import java.util.Properties;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.activation.DataHandler;
    import javax.mail.Message;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;
    import javax.mail.util.ByteArrayDataSource;
    
    public class Gmailer {
      private static final Logger LOGGER = Logger.getLogger(Gmailer.class.getName());
    
      public static void main(String[] args) {
        send();
      }
    
      public static void send() {
        Transport transport = null;
        try {
          String accountEmail = "[email protected]";
          String accountAppPassword = "";
          String displayName = "Display-Name 東";
          String replyTo = "[email protected]";
    
          String to = "[email protected]";
          String cc = "[email protected]";
          String bcc = "[email protected]";
    
          String subject = "Subject 東";
          String message = "<span style='color: red;'>東</span>";
          String type = "html"; // or "plain"
          String mimeTypeWithEncoding = "text/" + type + "; charset=" + StandardCharsets.UTF_8.name();
    
          File attachmentFile = new File("Attachment.pdf");
          // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
          String attachmentMimeType = "application/pdf";
          byte[] bytes = ...; // read file to byte array
    
          Properties properties = System.getProperties();
          properties.put("mail.debug", "true");
          // i found that this is the only property necessary for a modern java mail version
          properties.put("mail.smtp.starttls.enable", "true");
          // https://javaee.github.io/javamail/FAQ#getdefaultinstance
          Session session = Session.getInstance(properties);
    
          MimeMessage mimeMessage = new MimeMessage(session);
    
          // probably best to use the account email address, to avoid landing in spam or blacklists
          // not even sure if the server would accept a differing from address
          InternetAddress from = new InternetAddress(accountEmail);
          from.setPersonal(displayName, StandardCharsets.UTF_8.name());
          mimeMessage.setFrom(from);
    
          mimeMessage.setReplyTo(InternetAddress.parse(replyTo));
    
          mimeMessage.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
          mimeMessage.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc));
          mimeMessage.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc));
    
          mimeMessage.setSubject(subject, StandardCharsets.UTF_8.name());
    
          MimeMultipart multipart = new MimeMultipart();
    
          MimeBodyPart messagePart = new MimeBodyPart();
          messagePart.setContent(mimeMessage, mimeTypeWithEncoding);
          multipart.addBodyPart(messagePart);
    
          MimeBodyPart attachmentPart = new MimeBodyPart();
          attachmentPart.setDataHandler(new DataHandler(new ByteArrayDataSource(bytes, attachmentMimeType)));
          attachmentPart.setFileName(attachmentFile.getName());
          multipart.addBodyPart(attachmentPart);
    
          mimeMessage.setContent(multipart);
    
          transport = session.getTransport();
          transport.connect("smtp.gmail.com", 587, accountEmail, accountAppPassword);
          transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
        }
        catch(Exception e) {
          // I prefer to bubble up exceptions, so the caller has the info that someting went wrong, and gets a chance to handle it.
          // I also prefer not to force the exception in the signature.
          throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
        }
        finally {
          if(transport != null) {
            try {
              transport.close();
            }
            catch(Exception e) {
              LOGGER.log(Level.WARNING, "failed to close java mail transport: " + e);
            }
          }
        }
      }
    }
Reto Höhener
fonte