на главную обучение сертификация статьи литература ссылки гостевая книга
  Список статей Оглавление Текст статьи  

Java: Русские буквы и не только...

Автор:Астахов Сергей
Создан:03.06.2003


10. JavaMail

   Пакет JavaMail предназначен для работы с электронными письмами. При помощи этого пакета Вы можете отправлять и принимать письма через различные протоколы. Разные протоколы по разному обрабатывают национальные символы. Самые распространённые на данный момент протоколы Internet основаны на старом стандарте RFC-822. Согласно этому стандарту в служебных полях (заголовках) писем разрешено посылать только символы кодировки ASCII, т.е. только латинские буквы (первые 128 символов Unicode). Очевидно, что это неудобно, т.к. часто очень хочется писать, например в поле Subject (тема письма) или в полях From/To (имя и адрес отправителя/получателя) русский текст. Для того, чтобы решить эту проблему был придуман стандарт кодирования MIME (RFC 2047). Он позволяет в некоторых полях заголовка (не во всех) использовать национальные символы при помощи специального кодирования (Base64 или QuotedPrintable).

   Для представления писем в JavaMail используется класс javax.mail.Message. Это абстрактный класс, реальное же поведение определяется наследниками. Методы, определённые в нём работают только с обычными Java-строками (String). Для протоколов Internet обычно используется наследник javax.mail.internet.MimeMessage, который помимо базовых методов добавляет методы, в которых можно дополнительно указывать кодировку, которую следует использовать для писем. Для кодирования используется вспомогательный класс javax.mail.internet.MimeUtility. Класс MimeMessage обычно сам обращается к нему для кодирования/раскодирования заголовков, но, если Вы напрямую обращаетесь к заголовкам (методы getHeader()/setHeader()/addHeader()), то для их кодирования/раскодирования Вам придётся обращаться к методам MimeUtility самому.

   Если Вы не указываете кодировку письма, то будет использована кодировка по умолчанию - обычно используется file.encoding, но её можно перекрыть специальной системной настройкой "mail.mime.charset". Это разумно, т.к. часто кодировка по умолчанию в системе отличается от стандартной кодировки Internet. Для русскоязычных писем в Internet стандартом де-факто стала кодировка КОИ-8. Вы, конечно, можете указать и другую, но шанс, что принимающая сторона не сможет прочитать такое письмо очень велик.

   Надо учитывать также, что в JavaMail различаются два стандарта наименования кодировок - стандарт MIME и стандарт Java. Для большинства кодировок имена MIME уже поддерживаются в Java при помощи механизма синонимов. Например, для кодировки "Cp1251" (название Java) существует синоним "Windows-1251" (название MIME). Для тех кодировок, для которых такие синонимы отсутствуют, они поддерживаются внутри JavaMail. Для этого загружается файл javamail.charset.map из подкаталога "/META-INF" из того jar-файла, откуда был загружен пакет JavaMail. Для указания кодировки при вызове методов JavaMail следует использовать только MIME-имена, в противном случае получатель не сможет распознать использованную кодировку (если только на другом конце не тоже Java :-).

   Вот простой пример отправки письма при помощи JavaMail:
  import java.util.Properties;
  import javax.mail.Session;
  import javax.mail.Message;
  import javax.mail.Transport;
  import javax.mail.internet.MimeMessage;
  import javax.mail.internet.InternetAddress;

  public class MailTest{
    static final String ENCODING="koi8-r";
    static final String FROM="myaccount@mydomail.ru";
    static final String TO="myaccount@mydomail.ru";

    public static void main(String args[]) throws Exception{
	
      Properties mailProps=new Properties();
      mailProps.put("mail.store.protocol","pop3");
      mailProps.put("mail.transport.protocol","smtp");
      mailProps.put("mail.user","myaccount");
      mailProps.put("mail.pop3.host","mail.mydomail.ru");
      mailProps.put("mail.smtp.host","mail.mydomail.ru");

      Session session=Session.getDefaultInstance(mailProps);

      MimeMessage message=new MimeMessage(session);
      message.setFrom(new InternetAddress(FROM));
      message.setRecipient(Message.RecipientType.TO,
	    new InternetAddress(TO));
      message.setSubject("Тестовое письмо",ENCODING);
      message.setText("Текст тестового письма",ENCODING);

      Transport.send(message);
    }
  }


назад оглавление дальше