суббота, 1 октября 2016 г.

Отправка почтовых (email) сообщений на Java

В Java существует специальный пакет для работы с почтовыми сообщениями - javax.mail. С использованием классов этого пакета можно создавать email сообщения и отправлять их через SMTP сервер. В данной статье будут рассмотрены основные классы этого пакета и их методы, а также приведен пример простого класса, который можно использовать для отправки email сообщений в HTML формате.
Подключение библиотеки java.mail
Пакет java.mail не является стандартным пакетом java. Поэтому, чтобы начать с ним работать, прежде всего необходимо подключить его к проекту. Делается это по разному в зависимости от типа проекта. К примеру, для проекта на maven нужно добавить следующую зависимость
  
   <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4</version>
   </dependency>

Создание сессии
Прежде чем приступить к отправке сообщений необходимо создать объект класса javax.mail.Session. Создать сессию можно статическими методами Session.getInstance и Session.getDefaultInstance. Эти методы принимают в качестве параметра настройки SMTP клиента в виде объекта класса java.util.Properties.
При первом вызове метода Session.getDefaultInstance будет создан синглтон-экземпляр сессии с Properties, которые были переданы в качестве параметра. При дальнейших вызовах этого метода параметр Properties не будет оказывать никакого влияния на возвращаемый экземпляр сессии, а возвращаться будет всегда экземпляр, созданный при первом вызове. Если в вашем приложении предполагается оперировать с одним SMTP сервером с одинаковыми настройками для отправки всех сообщений - то можно использовать метод Session.getDefaultInstance, если будут производиться операции с несколькими SMTP серверами с разными настройками Properties - то следует использовать Session.getInstance.
Значения Properties обычно выставляются в зависимости от используемого SMTP сервера и типа соединения (SSL, TLS).
Например, для SMTP сервера Amazon можно использовать следующие параметры:
  
    Properties emailProperties = new Properties();      
    emailProperties.put("mail.transport.protocol", "smtp");
    emailProperties.put("mail.smtp.auth", "true");
    emailProperties.put("mail.smtp.starttls.enable", "true");
    emailProperties.put("mail.smtp.starttls.required", "true");

Также, используя Properties, можно включить режим отладки почтового клиента.

    
    emailProperties.put("mail.debug", "true");

В этом случае, при отправке email, в System.out будет дополнительно записываться отладочная информация.

Создание и инициализация сообщения
В java для представления email сообщения используется класс MimeMessage. При создании его можно связать с сессией (javax.mail.Session), передав её экземпляр в качестве параметра.
  
    MimeMessage message = new MimeMessage(mailSession);

Основные методы этого класса следующие:
  • setSubject - задает тему сообщения
  • setContent - задает контент сообщения. Имеется 2 перегруженных метода: setContent(Object o, String type) и setContent(Multipart mp). В общем случае, метод setContent(Object o, String type) позволяет передавать контент, помещенный в объект DataHandler.
    Проще всего задать контент сообщения передав его в виде HTML строки, например:
  •         
            String messageBody = "This is the body of message";
            message.setContent(messageBody, "text/html;charset=\"UTF-8\"");
    

    Однако, следует иметь ввиду, что чаще всего спам-фильтры снижают Spam Score сообщениям, у которых отсутствует альтернативная текстовая (text/plain) часть сообщения. Поэтому сообщения с контентом, представленным выше, будут иметь невысокий Spam Score, и, соответственно, с высокой вероятностью попадать в папку Спам получателя. Для увеличения Spam Score требуется, чтобы письма с контентом типа HTML содержали также текстовый вариант контента.
    Письмо с несколькими альтернативными контентами можно создать, используя класс MimeMultipart, передав в его конструктор строку "alternative".
            
            Multipart messageBody = new MimeMultipart("alternative");
    
            MimeBodyPart textPart = new MimeBodyPart();
            textPart.setContent(messageTextBody, "text/plain");
            messageBody.addBodyPart(textPart);
    
            MimeBodyPart htmlPart = new MimeBodyPart();
            htmlPart.setContent(messageHtmlBody, "text/html;charset=\"UTF-8\"");
            messageBody.addBodyPart(htmlPart);
            message.setContent(messageBody);
    

    При создании таких сообщений важно, чтобы тестовая часть сообщения была осмысленной, т.к. предполагается, что она будет показана пользователю в случае, если по каким либо причинам отобразить HTML часть сообщения окажется невозможно.

  • setFrom - задает имя и адрес отправителя. В качестве параметра может принимать объект класса расширяющего абстрактный класс Address. Можно создать свой подкласс определив все абстрактные методы, а можно использовать существующую имплементацию javax.mail.internet.InternetAddress. Конструктор класса InternetAddress в качестве первого параметра принимает email адрес отправителя, в качестве второго - имя отправителя, например new InternetAddress("vasiapupkin@gmail.com", "Vasia Pupkin"). Если вызвать метод без параметров, то в качестве адреса и имени отправителя будет использоваться адрес и имя локальной машины.

  • addRecipient - позволяет добавлять получателей сообщения. В качестве первого параметра принимает объект класса Message.RecipientType. В качестве второго - объект класса InternetAddress. Существуют следующие стандартные объекты класса Message.RecipientType: Message.RecipientType.TO - основной (первичный) получатель или получатели письма, Message.RecipientType.СС - вторичные получатели письма, Message.RecipientType.BСС - вторичные получатели письма, которые не будут видны другим получателям письма.

  • addHeader - позволяет добавлять заголовки письма. Используя заголовок, можно пометить email сообщение, как сообщение с высокой важностью: message.addHeader("Importance", "High");


Отправка сообщения происходит с использованием класса Transport. Чтобы создать объект класса Transport, использующий значения Properties заданные в Session, используется метод mailSession.getTransport. Подключение к серверу происходит c использованием метода Transport.connect. Отправка сообщения производится после подключения методом Transport.sendMessage. После окончания работы с объектом класса Transport важно всегда освобожать ресурсы используя метод Transport.close.

Ниже приведен пример класса, который осуществляет отправку email сообщения на указанный адрес, с указанными текстовым и html вариантами тела сообщения.

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
/**
 * Простой класс для отправки email сообщений
 * @author Cloud
 */
public class EmailMessageSender {
    private String mailServerHostName;
    private int mailServerPort;
    private String mailServerUsername;
    private String mailServerPassword;
    private String senderName;
    private String senderEmail;

    public EmailMessageSender(String mailServerHostName, int mailServerPort, String mailServerUsername,
                              String mailServerPassword, String senderName, String senderEmail) {
        this.mailServerHostName = mailServerHostName;
        this.mailServerPort = mailServerPort;
        this.mailServerUsername = mailServerUsername;
        this.mailServerPassword = mailServerPassword;
        this.senderName = senderName;
        this.senderEmail = senderEmail;
    }

    private Properties emailProperties = new Properties();
    {
        //emailProperties нужно выставить в соответствии с требованиями используемого SMTP сервера
        emailProperties.put("mail.transport.protocol", "smtp");
        emailProperties.put("mail.smtp.auth", "true");
        emailProperties.put("mail.smtp.starttls.enable", "true");
        emailProperties.put("mail.smtp.starttls.required", "true");
    }

    public void sendEmail(String recipientEmail, String subject,
                           String messageTextBody, String messageHtmlBody) throws MessagingException, UnsupportedEncodingException {
        Session mailSession = Session.getInstance(emailProperties);
        Transport transport = null;
        
        try {
            //region Создание multipart контента
            Multipart content = new MimeMultipart("alternative");
            MimeBodyPart textPart = new MimeBodyPart();
            textPart.setContent(messageTextBody, "text/plain");
            content.addBodyPart(textPart);
            MimeBodyPart htmlPart = new MimeBodyPart();
            htmlPart.setContent(messageHtmlBody, "text/html;charset=\"UTF-8\"");
            //endregion
            //region Инициализация MimeMessage
            MimeMessage message = new MimeMessage(mailSession);
            message.setSubject(subject, StandardCharsets.UTF_8.name());
            content.addBodyPart(htmlPart);
            message.setContent(content);
            message.setFrom(new InternetAddress(senderName, senderEmail));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipientEmail));
            //endregion
            transport = mailSession.getTransport();
            transport.connect(mailServerHostName, mailServerPort, mailServerUsername, mailServerPassword);
            transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
        } finally {
            if (transport != null) {
                try {
                    transport.close();
                } catch (MessagingException e) {
                    System.out.println("Ошибка при закрытии transport " + e.toString());
                }
            }
        }
    }

    public static void main(String[] args) {
        EmailMessageSender emailMessageSender = new EmailMessageSender("mailServerHostName", 587,
                "mailServerUsername", "mailServerPassword", "senderName@gmail.com", "Sender Name");
        try {
            emailMessageSender.sendEmail("recipientEmail@gmail.com", "test subject", "test body",
                    "html body");
        } catch (MessagingException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

Комментариев нет:

Отправить комментарий

Ярлыки

java (31) оптимизация (7) CPanel (5) svn (5) windows xp (5) ошибка (5) свой сервер (5) файлы и папки (5) gui (4) регулярные выражения (4) jacoco (3) redmine (3) windows (3) автоматизация (3) защита данных (3) резервное копирование (3) сервер (3) JavaScript (2) Oracle SQL (2) adsl модем (2) apache maven (2) apache tomcat (2) coverage (2) dropbox (2) excel (2) firewall (2) netbeans (2) office 2007 (2) samsung (2) system tray (системный трей) (2) xerox (2) вирусы (2) принтер (2) сериализация (2) удаленный рабочий стол (2) HTML (1) JFileChooser (1) MySQL (1) Nokia (1) Ovi (1) P660R-T1 (1) WakeOnLan (1) blogger.com (1) ctfmon.exe (1) email (1) flash память (1) ftp (1) integration testing (1) ip (1) jQuery (1) jvisualWm (1) log4j (1) look and feel (1) myBatis (1) php (1) serialVersionUID (1) skype (1) smtp (1) ssh (1) swing (1) torrents (1) unit-testing (1) unix (1) vpn (1) windows 7 (1) xStarter (1) zip (1) безопасность (1) вход в систему (1) дизайн (1) документация (1) заправка (1) интернет (1) логирование (1) мышь (1) патч (1) перенос (1) печать (1) плагины (1) почтовые сообщения (1) программирование (1) процессы (1) прошивка (1) сеть (1) сеть. ошибка (1) скрытые файлы (1) списки (1) фильтрация (1) фокус (1) часовые пояса (1) шифрование (1) экран (1)