Как настроить среду для использования JavaMail? - PullRequest
3 голосов
/ 22 декабря 2009

Мне нужно отправить простое html-сообщение с помощью JavaMail. И когда я пытался найти несколько хороших примеров с объяснениями в Интернете, каждый следующий пример вызывал у меня еще большую злость и злость.

Все эти глупые примеры содержат скопированный и вставленный Java-код, который отличается только комментариями, и приятный отказ от ответственности, что сначала вы должны сконфигурировать ваш smtp и pop3 сервер.

Я понимаю, что никто не хочет делать рекламу для некоторых конкретных продуктов, но настройка сервера - это самая сложная часть. Итак, кто-нибудь может дать мне действительно полезную информацию (без кода Java) о настройке конкретного сервера (например, Kerio или любого другого)?

Теперь у меня есть следующее исключение:

250 2.0.0 Reset state
javax.mail.SendFailedException: Invalid Addresses;
  nested exception is:
    com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 Relaying to <mymail@mycompany.com> denied (authentication required)

UPD. Простая переформулировка всего предыдущего текста такова: представьте, что у вас Windows, jdk и больше ничего. И вы хотите сделать Java-программу и запустить ее на своем компьютере. И эта программа должна отправить "Привет, мир!" на вашу учетную запись Gmail. Перечислите свои шаги.

UPD2. Вот код:

Properties props = new Properties ();
props.setProperty ("mail.transport.protocol", "smtp");
props.setProperty ("mail.host", "smtp.gmail.com");
props.setProperty ("mail.user", "my_real_address_1@gmail.com");
props.setProperty ("mail.password", "password_from_email_above"); 

Session mailSession = Session.getDefaultInstance (props, null);
mailSession.setDebug (true);
Transport transport = mailSession.getTransport ();

MimeMessage message = new MimeMessage (mailSession);
message.setSubject ("HTML  mail with images");
message.setFrom (new InternetAddress ("my_real_address_1@gmail.com"));
message.setContent ("<h1>Hello world</h1>", "text/html");
message.addRecipient (Message.RecipientType.TO,
        new InternetAddress ("my_real_address_2@gmail.com"));

transport.connect ();
transport.sendMessage (message,
        message.getRecipients (Message.RecipientType.TO));

И исключение:

RSET
250 2.1.5 Flushed 3sm23455365fge.10
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. 3sm23455365fge.10
    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1829)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1368)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:886)
    at com.teamdev.imgmail.MailSender.main(MailSender.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...

Ответы [ 4 ]

13 голосов
/ 22 декабря 2009

Если вы ищете учебник по настройке SMTP-сервера, вам не нужно искать JavaMail. Просто найдите учебное пособие на выбранном вами сервере ( Kerio , например ... или Exim , SendMail , Apache James , Постфикс ) или спросите на Ошибка сервера . Любой SMTP-совместимый сервер будет прекрасно работать с JavaMail.

В качестве альтернативы, вы можете даже использовать любую "стандартную" инфраструктуру почтового провайдера. Например, я использую учетную запись Google Apps вместе с SMTP-инфраструктурой Google для отправки почты из наших приложений Java. Использование учетной записи Gmail в любом случае является хорошей отправной точкой, если вы не хотите настраивать собственный SMTP-сервер, чтобы просто протестировать JavaMail.

В качестве последнего варианта вы можете даже просмотреть MX-записи для домена и доставить почту непосредственно на SMTP-сервер получателя. Есть несколько распространенных ошибок, которые стоит обойти.

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

Кстати: что касается отправленного вами сообщения об ошибке: SMTP-сервер запрещает ретрансляцию сообщений. Это если ваш SMTP-сервер (считает, что он) работает на example.com, и вы отправляете как bob@example.net на alice@example.org, вы просите SMTP-сервер действовать как ретранслятор. Это было обычной практикой несколько лет назад, до тех пор, пока ее, как вы уже догадались, не использовали спамеры. С тех пор почтмейстерам рекомендуется отрицать ретрансляцию. У вас есть два варианта: аутентифицироваться перед отправкой почты или отправлять учетные записи, размещенные только на вашем сервере (например, на example.com, например, alice@example.com).

Edit:

Вот код, который поможет вам начать аутентификацию g (работает с учетными записями Gmail, но также и для вашего собственного сервера)

private Session createSmtpSession() {
  final Properties props = new Properties();
  props.setProperty("mail.smtp.host", "smtp.gmail.com");
  props.setProperty("mail.smtp.auth", "true");
  props.setProperty("mail.smtp.port", "" + 587);
  props.setProperty("mail.smtp.starttls.enable", "true");
  // props.setProperty("mail.debug", "true");

  return Session.getDefaultInstance(props, new javax.mail.Authenticator() {

    protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication("john.doe@gmail.com", "mypassword");
    }
  });
}
2 голосов
/ 10 октября 2011

Рабочий пример, объединяющий приведенные выше ответы с использованием активации-1.1.jar и mail-1.4.1.jar , а хост SMTP - Gmail .

  1. Заменить user@gmail.com и user_pw в строке return new PasswordAuthentication("user@gmail.com", "user_pw");

  2. Кроме того, вы хотите заменить myRecipientAddress@gmail.com на адрес электронной почты, на который хотите получить письмо.

    package com.test.sendEmail;
    import java.util.Properties;
    import javax.mail.*;
    import javax.mail.internet.*;
    
    public class sendEmailTest {
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        sendEmailTest emailer = new sendEmailTest();
        //the domains of these email addresses should be valid,
        //or the example will fail:
        emailer.sendEmail();
    }
    
    /**
      * Send a single email.
      */
    public void sendEmail(){
    Session mailSession = createSmtpSession();
    mailSession.setDebug (true);
    
    try {
        Transport transport = mailSession.getTransport ();
    
        MimeMessage message = new MimeMessage (mailSession);
    
        message.setSubject ("HTML  mail with images");
        message.setFrom (new InternetAddress ("myJavaEmailSender@gmail.com"));
        message.setContent ("<h1>Hello world</h1>", "text/html");
        message.addRecipient (Message.RecipientType.TO, new InternetAddress ("myRecipientAddress@gmail.com"));
    
        transport.connect ();
        transport.sendMessage (message, message.getRecipients (Message.RecipientType.TO));  
    }
    catch (MessagingException e) {
        System.err.println("Cannot Send email");
        e.printStackTrace();
    }
    }
    
    private Session createSmtpSession() {
    final Properties props = new Properties();
    props.setProperty ("mail.host", "smtp.gmail.com");
    props.setProperty("mail.smtp.auth", "true");
    props.setProperty("mail.smtp.port", "" + 587);
    props.setProperty("mail.smtp.starttls.enable", "true");
    props.setProperty ("mail.transport.protocol", "smtp");
    // props.setProperty("mail.debug", "true");
    
    return Session.getDefaultInstance(props, new javax.mail.Authenticator() {
      protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("user@gmail.com", "user_pw");
      }
    });
    }
    
    }
    
1 голос
/ 22 декабря 2009

Я вижу часть вашей проблемы. Это адекватно объяснено в сообщении об ошибке.

SMTP-сервер, на который вы отправляете свою почту (т.е. один из адресов, настроенных вами в конфигурации JavaMail), отказывается пересылать почту на mymail@company.com. Похоже, проблема конфигурации в вашем SMTP-сервере. Как указал sfussenegger, он не имеет ничего общего с javamail.

Так что вы не выполняете отладку на всех фронтах одновременно, возможно, стоит попробовать обратиться к вашему SMTP-серверу с известного работающего SMTP-клиента. Например, с Thunderbird все будет хорошо. Если вы можете отправлять через него почту из Thunderbird, с JavaMail не должно возникнуть никаких проблем.


Обновление:

Правильный адрес для SMTP-сервера Google: smtp.gmail.com. Это сервер, который вы настроили в JavaMail? Можете ли вы показать нам соответствующее сообщение об ошибке?

0 голосов
/ 22 декабря 2009

Это должно работать:

import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;

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

public class Emailer {

    public static void main(String[] args) {

        String hostname = args[0];
        final String userName = args[1];
        final String passWord = args[2];
        String toEmail = args[3];
        String fromEmail = args[4];
        String subject = args[5];
        String body = "";
        // add rest of args as one body text for convenience
        for (int i = 6; i < args.length; i++) {
            body += args[i] + " ";
        }

        Properties props = System.getProperties();
        props.put("mail.smtp.host", hostname);

        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(userName, passWord);
            }
        });

        MimeMessage message = new MimeMessage(session);
        try {
            message.setFrom(new InternetAddress(fromEmail));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
            message.setSubject(subject);
            message.setText(body);
            Transport.send(message);

        } catch (MessagingException e) {
            System.out.println("Cannot send email " + e);
        }
    }
}

Вам нужно поместить JavaMail mail.jar в ваш путь к классам для зависимостей javax.mail. Я не уверен, что Google позволяет отправлять электронную почту так, как вы хотите. Как насчет того, чтобы попробовать другого почтового провайдера, такого как ваш провайдер?

...