Как я могу отправить электронное письмо с помощью приложения Java с помощью GMail, Yahoo или Hotmail?

Можно ли отправить электронное письмо из моего Java-приложения, используя учетную запись GMail? Я настроил почтовый сервер моей компании с приложением Java для отправки электронной почты, но это не повлияет на его распространение при распространении приложения. Приемлемы любые ответы с использованием Hotmail, Yahoo или GMail.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
211
0
249 280
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Простым путем было бы настроить / включить учетную запись Gmail для доступа по протоколу POP3. Это позволит вам отправлять сообщения через обычный SMTP через серверы Gmail.

Затем вы просто отправляете через smtp.gmail.com (на порт 587)

Примерно так (похоже, вам просто нужно сменить 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();

Можно ли отправить контент в формате html? Если я попытаюсь написать какой-нибудь html-код и отправить его, но на стороне приема, содержимое электронного письма будет только html-кодом.

Thang Pham 21.02.2011 19:35

Чтобы отправить тело html вместо открытого текста, измените эту строку: message.setText("Welcome to JavaMail"); на эту строку: message.setContent("<h1>Hello world</h1>", "text/html");

mist 29.06.2011 00:36

Этот отсутствует ("mail.smtp.starttls.enable", "true")

Sotomajor 03.10.2012 16:35

не нужно импортировать какую-то javalibrary? и @Sotomajor, где мы используем эту недостающую строку?

gumuruh 17.07.2017 07:43

@gumuruh в реквизите. Должен был быть props.put("mail.smtp.starttls.enable", "true")

Sotomajor 17.07.2017 16:51
Ответ принят как подходящий

Сначала загрузите JavaMail API и убедитесь, что соответствующие файлы jar находятся в вашем пути к классам.

Вот полный рабочий пример с использованием 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();
        }
    }
}

Естественно, вы захотите сделать больше в блоках catch, чем распечатать трассировку стека, как я сделал в приведенном выше примере кода. (Удалите блоки catch, чтобы увидеть, какие вызовы методов из JavaMail API вызывают исключения, чтобы вы могли лучше понять, как правильно их обрабатывать.)


Спасибо @jodonnel и всем, кто ответил. Я назначаю ему награду, потому что его ответ привел меня примерно на 95% к полному ответу.

ящерица - нужно ли для этого пробросить порт ??? props.put ("mail.smtp.port", "587"); этот порт должен быть открыт ??

Varun 05.04.2011 08:19

@varun: Это порт на сервере исходящей почты smtp.gmail.com. Подробнее см. Настройка других почтовых клиентов.

Bill the Lizard 05.04.2011 15:11

Я единственный, кто получает здесь исключение AuthenticationFailedException props.put ("mail.smtp.auth", "true"); если истина - строка. Хорошо, если это логическое значение.

nyxz 20.12.2011 16:39

это не сработало, если только session.getTransport ("smtp") не был session.getTransport ("smtps")

Michael Roller 21.08.2012 09:54

Для SSL-соединения Gmail используйте props.put ("mail.smtp.port", "465"); // вместо 587

Tomasz Dziurko 20.12.2012 17:47

Похоже, что это не работает сейчас (сентябрь 13), по крайней мере, для gmail. Вы получаете сообщение «Ошибка построения пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: не удалось найти действительный путь сертификации для запрошенной цели». Я считаю, что на стороне Gmail есть некоторые изменения в сертификатах и ​​протоколах.

mtk 28.09.2013 21:42

@billtheLizard На самом деле не уверен, в чем проблема. Я получаю ту же ошибку, что и указано выше, и нахожу несколько других сообщений, относящихся к этой ошибке. Но решить пока не удалось. Я считаю, что должны быть некоторые различия в зависимости от того, в каком регионе он выполняется.

mtk 13.10.2013 21:21

См. oracle.com/technetwork/java/faq-135477.html#getdefaultinstan‌ ce относительно использования Session.getDefaultInstance (свойства). В этом FAQ рекомендуется вместо этого использовать getInstance (..).

Bryan 12.12.2013 22:04

Мне не удалось получить доступ с помощью SMTP gmail с указанными выше и аналогичными кодами, и я получал javax.mail.AuthenticationFailedException, и мне пришлось явно включить «менее безопасные приложения» в моих настройках Gmail: google.com/settings/security/lesssecureapps. После включения «менее безопасных приложений» код заработал.

Marcus Junius Brutus 30.09.2014 02:19

@BilltheLizard привет. Этот код работает нормально .. но как я могу прикрепить изображение к письму ..? message.setFileName (имя файла); отправить изображение .. но размер изображения уменьшен до 1кб. поэтому я не могу открыть image.plz help.thanks.

Dinoop Nair 03.02.2015 09:17

Зачем использовать System.getProperties() вместо нового Properties()? Использование системных свойств может иметь непредвиденные побочные эффекты, а в многопоточном сценарии вы можете в конечном итоге отправить электронные письма неправильным получателям и т. д. Кроме того, как упоминает @Bryan, FAQ JavaMail рекомендует использовать Session.getInstance(properties) вместо Session.getDefaultInstance(properties). В любом случае ваш ответ очень помог, так что спасибо :)

Alix 15.10.2015 17:59

javax.mail.MessagingException: не удалось подключиться к хосту SMTP: smtp.gmail.com, порт: 587; Все еще получаю это с вашим кодом

Vinay Prajapati 26.04.2018 08:43

@BilltheLizard БОЛЬШОЕ СПАСИБО ... ЭТО помогло мне отправить электронное письмо. Только одно сомнение, я использую локальный хост, мой веб-сайт не зарегистрирован как SSL, могу ли я использовать SSL-порт 465 вместо 587 TLS при отправке электронной почты в приведенном выше коде?

Tom 17.08.2019 04:23

Привет том. Я действительно мало что знаю об этом, поэтому я рекомендую вам попробовать. Это или задайте отдельный вопрос и укажите этот. Удачи!

Bill the Lizard 17.08.2019 23:05

Несмотря на то, что этот вопрос закрыт, я хотел бы опубликовать встречное решение, но теперь использующее Простая почта Java (SMTP-оболочка 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);

Я получаю сообщение об ошибке с этим кодом: «Сообщение: Общая ошибка: 530 5.7.0 Сначала необходимо выполнить команду STARTTLS» - как включить starttls с помощью vesijama?

iddqd 20.03.2011 20:39

Я получил ошибку «Сначала необходимо выполнить команду STARTTLS», потому что в строке ниже я использовал переменную isStartTlsEnabled как логическое значение, а не как String: props.put ("mail.smtp.starttls.enable", isStartTlsEnabled);

user64141 17.01.2014 20:35

От этот ответ: Чтобы использовать TLS, вы можете сделать что-то вроде new Mailer(your login / your session, TransportStrategy.SMTP_TLS).sendMail(email);

Benny Bottema 20.10.2015 10:27

Это то, что я делаю, когда хочу отправить электронное письмо с вложением, все работает нормально. :)

 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);
        }
    }

}

У других людей есть хорошие ответы выше, но я хотел бы добавить сюда заметку о своем опыте. Я обнаружил, что при использовании Gmail в качестве SMTP-сервера исходящей почты для моего веб-приложения Gmail позволяет мне отправлять только около 10 сообщений, прежде чем ответить антиспамовым ответом, который мне нужно вручную выполнить, чтобы повторно включить доступ SMTP. Электронные письма, которые я отправлял, не были спамом, а были «приветственными» письмами, когда пользователи регистрировались в моей системе. Итак, YMMV, и я бы не стал полагаться на Gmail в качестве производственного веб-приложения. Если вы отправляете электронную почту от имени пользователя, например, установленного настольного приложения (где пользователь вводит свои учетные данные Gmail), возможно, все в порядке.

Кроме того, если вы используете Spring, вот рабочая конфигурация для использования Gmail для исходящего SMTP:

<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>

Спасибо, Джейсон, за пример настроек конфигурации и за предупреждение об ограничениях исходящей почты. Я никогда раньше не сталкивался с этим пределом, но уверен, что другие люди найдут эту информацию полезной.

Bill the Lizard 18.06.2009 21:29

Я хотел бы узнать больше об этом ограничении спама ... Мне нужно отправить несколько писем, следует ли разделить их на группы? ждать указанное количество времени? Кто-нибудь знает подробности ограничений почты Google?

opensas 12.04.2010 00:25

//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;
        }
    }

}

Мой полный код, как показано ниже, работает хорошо:

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

Опубликованные решения кода могут вызвать проблемы, когда вам нужно настроить несколько сеансов SMTP в любом месте одной JVM.

В FAQ по JavaMail рекомендуется использовать

Session.getInstance(properties);

вместо

Session.getDefaultInstance(properties);

потому что getDefault будет использовать только свойства, указанные при первом вызове. Все последующие использования экземпляра по умолчанию будут игнорировать изменения свойств.

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

Привет, попробуйте этот код ....

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

Требуется минимум:

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);
    }

}

@ AlikElizin-kilaka Я пытался использовать свой идентификатор Gmail как для отправителя, так и для получателя, но обнаружил, что вам также необходимо установить флаг Разрешить менее безопасные приложения в положение ВКЛ. В настройках учетной записи Google, поскольку вы получаете доступ к своему профилю Gmail в менее безопасном путь. Только тогда вы сможете увидеть письмо, отправленное клиентом Java. В противном случае вы получите javax.mail.AuthenticationFailedException.

kunal 16.09.2017 04:09

Вот простой в использовании класс для отправки писем с помощью Gmail. У вас должна быть библиотека JavaMailдобавлен в ваш путь сборки или просто использовать 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;
    }
}

Пример использования:

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();

Если вы хотите использовать Outlook с Javamail API, используйте

smtp-mail.outlook.com

как хозяин для более полного рабочего кода Посмотрите этот ответ.

Добавленная стоимость:

  • подводные камни кодирования в теме, сообщении и отображаемом имени
  • только одно волшебное свойство необходим для современных версий почтовых библиотек Java
  • Session.getInstance() рекомендуется вместо Session.getDefaultInstance()
  • вложение в том же примере
  • еще работает после Google отключает небезопасные приложения: включить двухфакторную аутентификацию в вашей организации -> включить двухфакторную аутентификацию -> сгенерировать пароль приложения.
    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);
            }
          }
        }
      }
    }

Другие вопросы по теме