Подтвердить что ты не робот

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

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

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

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

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

В интерфейсе 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);
}
4b9b3361

Ответ 1

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

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

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

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

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

Платит очень внимательно читать javadocs.

Ответ 3

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

В java-документе говорится

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

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