javax.mail.Session有什么作用?

14

我正在修复一个负责发送电子邮件的类。它看起来像这样(简化):

/* ... */
Properties props = System.getProperties();
props.put("mail.smtp.host", A_VALID_IP_OF_MAIL_SERVER);
Session session = Session.getDefaultInstance(props, null);  

try {
    Message msg = new MimeMessage(session);
    /* msg.setFrom(); msg.addRecipient(); etc. */
    Transport.send(msg);
    System.out.println("Sent!");
}
catch (Exception e) { /* ... */ }
/* ... */
在我的工作中,我将session设置为null,令我非常惊讶的是,类仍然可以正常工作。如果我把null传递给MimeMessage构造函数也没有关系,它不会抛出异常或其他任何错误。此外,Transport.send()方法包括以下几行代码: 240 Session s = (msg.session != null) ? msg.session : 241 Session.getDefaultInstance(System.getProperties(), null); 因此,如果sessionnull,它只会使用系统属性创建一个新的Session对象。那么创建Session对象的目的是什么呢?如果无论传递什么参数都没有关系,为什么MimeMessage没有一个默认的构造函数呢?
我查看了一些使用javax.mail的示例,例如:Google的示例和tutorialspoint的示例,它们都创建了一个似乎很无用的Session对象。为什么会有人这样做呢?

这很好用,直到你开始在多线程应用程序中使用Javamail,那么它最终会咬你一口,因为System.getProperties()是一个全局对象。 - Brain2000
1个回答

15
创建Session对象的目的是什么?
会话是与邮件主机交互的上下文。这包括但不限于来自邮件主机的调试输出、超时和身份验证机制。如果您想以不同的方式与同一邮件主机进行交互,那么会话就是保存此信息的对象。
如果单个JVM需要连接到多个邮件服务器,则需要两个不同的会话。这在JavaMail FAQ中有详细解释:
“如果同一个JVM中的其他代码(例如,在同一个应用程序服务器中)已经使用其属性创建了默认的会话,则您可能会使用他们的会话,并且您的属性将被忽略。这通常解释了为什么您的属性设置似乎被忽略。始终使用Session.getInstance避免此问题。”
大多数JavaMail示例都无法通过常见错误测试。尝试参考JavaMail API示例程序。对于任何代码,Session.getDefaultInstance很少是正确的选择。大多数代码应该使用Session.getInstance。为MimeMessage包含默认构造函数只会鼓励错误行为。

此外...支持空会话主要是为了在人们出现错误并未创建会话的情况下提供一些合理的行为。 - Bill Shannon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接