私は小さなJavaアプリをJavaMailを使用してユーザーに自動メールを送信するアプリを書いています。今のところ2つのポート(25と587)から選択できます。ポートは無線で選択できますGUIのボタン。
ユーザーがメール設定(ポートを含む)をテストできるように、テストボタンを追加しました。ただし、何らかの理由で、ユーザーがテストメールを送信しようとすると、ポートを変更できなくなります。 Javamailは常に元のテスト電子メールのポートを使用します。
例:ユーザーがポート25でメールを送信しようとすると、JavaMailはポート25に接続できないと言っています(たとえば、SMTPホストが別のポートを使用している)。ユーザーはポート587をクリックし、新しい電子メールを送信しようとします。 JavaMailは再びポート25に接続できないというエラーをスローします。
なんでか困ってます。新しいテストメールが送信されるたびに、まったく新しいSendMailUsingAuthenticationオブジェクトが作成されます。そのクラス内では、プロパティは常に適切なポートにリセットされます。私がデバッグできる限り、すべての変数は正しく、正しいポートに関連付けられています。 Transportの内部で何か欠けていることはありますか?
フロントエンド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);
}
これは、getDefaultInstance()
which says を使用しているために発生します。
デフォルトのSessionオブジェクトを取得します。デフォルトがまだセットアップされていない場合、新しいSessionオブジェクトが作成され、デフォルトとしてインストールされます。
また、Properties
引数は「新しいSessionオブジェクトが作成された場合にのみ使用されます」。
そのため、最初にgetDefaultInstance
を呼び出すと、指定したポートが使用されます。その後、Session
はすでに作成されており、その後のgetDefaultInstance
の呼び出しは同じセッションを返し、変更されたプロパティを無視します。
Session.getInstance()
の代わりにgetDefaultInstance()
を使用してみてください。これにより、提供されたプロパティを使用して、毎回新しいSession
が作成されます。
Javadocsを非常に注意深く読むことは価値があります。
"Transport.send(msg)"は、プロパティで提供している接続の詳細を考慮していないと思います。デフォルトで定義されている接続を使用します。
Java docは言う
"sendは独自の接続を作成および管理する静的メソッドであることに注意してください。**このメソッドの呼び出しに使用されるトランスポートインスタンスに関連付けられた接続は無視され、使用されません。このメソッドは、 Transport.send(msg);の形式で、インスタンス変数を使用して呼び出すことはできません。 "**
代わりに、Transport.connect(smtphost、smtpport、user、password)を試してみましたが、うまく機能します。
PlzはSessionクラスの2つのメソッドを比較します: Session.getDefaultInstance(Properties、Authenticator) および Session.getInstance(Properties、Authenticator)
まだ問題が発生している他の人のためのヒント、私たちはSession.getInstance
およびポートはstillで、デフォルトは25でした。
結局のところ、Long
にする必要がある場合、prop値をString
として設定していました。
エラーも警告もログも記録せず、デフォルトは25でした。