如何更改 JavaMail 端口

Posted

技术标签:

【中文标题】如何更改 JavaMail 端口【英文标题】:How to change JavaMail port 【发布时间】:2012-02-04 23:16:00 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

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

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

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

仔细阅读 javadocs 是值得的。

【讨论】:

【参考方案2】:

提示其他仍有问题的人,我们使用的是 Session.getInstance,端口仍然默认为 25。

事实证明,我们在需要 String

时将 prop 值设置为 Long

它没有错误、警告或日志,只是默认为 25。

【讨论】:

我想给这个投票十次。我最初是从一个道具文件中读取的,所有电子邮件参数都是字符串——我的电子邮件在端口 587 上发送就好了。实现已更改为使用将端口指定为 int 的对象,并且电子邮件停止工作 - 默认为端口 25。使用字符串!!!【参考方案3】:

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

java 文档说

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

相反,我尝试使用 Transport.connect(smtphost,smtpport,user,password) 并且效果很好。

【讨论】:

【参考方案4】:

请比较一下Session类的两个方法:Session.getDefaultInstance(Properties, Authenticator)和Session.getInstance(Properties, Authenticator)

【讨论】:

以上是关于如何更改 JavaMail 端口的主要内容,如果未能解决你的问题,请参考以下文章

使用JavaMail发送邮件,465端口开启ssl加密传输

IMAP:(JavaMail)UIDVALIDTY 值总是更改某些文件夹

javamail 发送邮件(SSL)

springboot集成junit测试与javamail测试遇到的问题

Java专题十七:JavaMail

JavaMail邮件发送