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

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

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

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

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

в интерфейсе GUI:

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 ответов


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

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

и "используется только при создании нового объекта сеанса."

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

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

стоит очень внимательно прочитать javadocs.


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

Java doc говорит

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

вместо этого я попытался с транспортом.подключения(smtphost,smtpport,пользователь,пароль) и он работает довольно хорошо.