Как изменить порт JavaMail - PullRequest
       13

Как изменить порт JavaMail

15 голосов
/ 07 января 2012

Я пишу небольшое приложение на Java с использованием JavaMail, которое отправляет пользователю автоматическое электронное письмо. Они могут выбирать между (на данный момент) двумя портами: 25 и 587. Порт можно выбрать с помощью переключателя на графическом интерфейсе.

Я добавил тестовую кнопку, чтобы позволить пользователю проверить настройки электронной почты (включая порт). Однако по какой-то причине, когда пользователь пытается отправить тестовое письмо, порт не может быть изменен. Javamail всегда будет использовать порт оригинальной тестовой электронной почты.

Пример. Пользователь пытается отправить электронное письмо через порт 25, а JavaMail сообщает, что не может подключиться к порту 25 (например, узел SMTP использует другой порт). Пользователь щелкает порт 587 и пытается отправить новое электронное письмо. JavaMail выдает ошибку, говоря, что не может подключиться к порту 25, снова.

Я немного озадачен, почему. Каждый раз, когда отправляется новое тестовое письмо, создается совершенно новый объект SendMailUsingAuthentication. Внутри этого класса свойства всегда сбрасываются на соответствующий порт. Всякий раз, когда я отлаживаю, насколько я вижу, все переменные верны и связаны с правильным портом. Что-то происходит внутри транспорта, что мне не хватает?

В графическом интерфейсе пользователя:

private void testButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           

    int port = port25RadioButton.isSelected() ? PORT_25 : PORT_587;
    notifier = new SendMailUsingAuthentication(hostNameTextField.getText(),
            userTextField.getText(), getPassword(), emailTextField.getText().split(","),port);


    Thread wait = new Thread(new Runnable() {

        public void run() {
            try {
                changeStatusText("Sending test email...");
                notifier.postTestMail();
                changeStatusText("Test email sent.");
            } catch (AddressException ex) {
                changeStatusText("Error.  Invalid email address name.");
            } catch (MessagingException ex) {
                changeStatusText("SMTP host connection refused.");
                System.err.println(ex.getMessage());
            } catch (Exception ex) {
                System.err.println(ex);
            }
        }
    });

    wait.start();
}

В классе отправителя электронной почты:

public void postTestMail() throws MessagingException, AddressException{
    String[] testReciever = new String[1];
    testReciever[0] = emailList[0];
    postMail(testReciever, "Test email.", "Your email settings are successfully set up.", emailFromAddress);
}

private void postMail(String recipients[], String subject,
        String message, String from) throws MessagingException, AddressException {

    //Set the host smtp address
    Properties props = new Properties();
    props.put("mail.smtp.port", smtpPort);
    props.put("mail.smtp.host", smtpHostName);
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", true);
    Authenticator auth = new SMTPAuthenticator();
    Session session = Session.getDefaultInstance(props, auth);
    session.setDebug(false);

    // create a message
    Message msg = new MimeMessage(session);

    // set the from and to address
    InternetAddress addressFrom = new InternetAddress(from);
    msg.setFrom(addressFrom);

    InternetAddress[] addressTo = new InternetAddress[recipients.length];
    for (int i = 0; i < recipients.length; i++) {
        addressTo[i] = new InternetAddress(recipients[i]);
    }
    msg.setRecipients(Message.RecipientType.TO, addressTo);

    // Setting the Subject and Content Type
    msg.setSubject(subject);
    msg.setContent(message, "text/plain");
    Transport.send(msg);
}

Ответы [ 3 ]

23 голосов
/ 07 января 2012

Это происходит потому, что вы используете getDefaultInstance(), что говорит :

Получить объект сеанса по умолчанию.Если значение по умолчанию еще не было установлено, новый объект Session создается и устанавливается в качестве значения по умолчанию.

И что аргумент Properties используется «только в случае создания нового объекта Session».

Итак, при первом вызове getDefaultInstance он использует указанный вами порт.После этого Session уже был создан, и последующие вызовы getDefaultInstance вернут тот же сеанс и проигнорируют измененные свойства.

Попробуйте использовать Session.getInstance() вместо getDefaultInstance(), что создаетновый Session каждый раз, используя предоставленные свойства.

Очень внимательно читать Javadocs.

3 голосов
/ 28 августа 2014

Я думаю, что "Transport.send (msg)" не будет учитывать детали подключения, которые вы предоставляете в своих свойствах.Он будет использовать свое соединение, которое определено по умолчанию.

В документе Java сказано:

"Обратите внимание, что send - это статический метод, который создает и управляет своим собственным соединением. ** Любое соединениесвязанный с любым экземпляром Transport, используемым для вызова этого метода, игнорируется и не используется. Этот метод должен вызываться только с использованием формы Transport.send (msg); и никогда не должен вызываться с использованием переменной экземпляра. "**

Вместо этого я попробовал использовать Transport.connect (smtphost, smtpport, user, password), и он работает довольно хорошо.

2 голосов
/ 07 января 2012
...