如何更改JavaMail端口

我正在使用JavaMail编写一个小型Java应用程序,它向用户发送自动电子邮件。 他们可以选择(现在)两个端口: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); } 

发生这种情况是因为您使用的是getDefaultInstance() ,它说 :

获取默认的Session对象。 如果尚未设置默认值,则会创建一个新的Session对象并将其安装为默认值。

并且Properties参数“仅在创建新的Session对象时使用”。

因此,第一次调用getDefaultInstance它会使用您指定的端口。 之后, Session已经创建,随后对getDefaultInstance调用将返回相同的会话,并忽略更改的属性。

尝试使用Session.getInstance()而不是getDefaultInstance() ,它使用提供的属性每次创建一个新的Session

非常仔细地阅读javadoc是值得的。

我认为“Transport.send(msg)”不会考虑您在属性中提供的连接详细信息。 它将使用默认定义的连接。

java doc说

“请注意,send是一个静态方法,用于创建和管理自己的连接。**与用于调用此方法的任何Transport实例关联的任何连接都将被忽略并且不被使用。此方法只能使用表单Transport.send(msg)调用);,并且永远不应该使用实例变量调用。“**

相反,我尝试使用Transport.connect(smtphost,smtpport,用户,密码),它运行良好。

Plz比较Session类的两种方法: Session.getDefaultInstance(Properties,Authenticator)和Session.getInstance(Properties,Authenticator)