10

我想发送邮件而不用打扰用于传递的 SMTP 服务器。

所以JavaMail API对我不起作用,因为我必须指定一个 SMTP 服务器来连接。

我希望库通过查询邮件地址域的 MX 记录自行找出哪个 SMTP 服务器负责哪个电子邮件地址。

我正在寻找类似阿司匹林的东西。不幸的是,我不能使用阿司匹林本身,因为开发在 2004 年停止并且库无法与现代垃圾邮件强化服务器正确通信。

一个可嵌入版本的James可以完成这项任务。但我还没有找到关于这是否可能的文档。

或者有人知道我可以使用的其他库吗?

4

3 回答 3

15

一种可能的解决方案:自己获取 MX 记录并使用JavaMail API

您可以使用dnsjava项目获取 MX 记录:

Maven2依赖:

<dependency>
    <groupId>dnsjava</groupId>
    <artifactId>dnsjava</artifactId>
    <version>2.0.1</version>
</dependency>

MX记录检索方法:

public static String getMXRecordsForEmailAddress(String eMailAddress) {
    String returnValue = null;

    try {
        String hostName = getHostNameFromEmailAddress(eMailAddress);
        Record[] records = new Lookup(hostName, Type.MX).run();
        if (records == null) { throw new RuntimeException("No MX records found for domain " + hostName + "."); }

        if (log.isTraceEnabled()) {
            // log found entries for debugging purposes
            for (int i = 0; i < records.length; i++) {
                MXRecord mx = (MXRecord) records[i];
                String targetString = mx.getTarget().toString();
                log.trace("MX-Record for '" + hostName + "':" + targetString);
            }
        }

        // return first entry (not the best solution)
        if (records.length > 0) {
            MXRecord mx = (MXRecord) records[0];
            returnValue = mx.getTarget().toString();
        }
    } catch (TextParseException e) {
        throw new RuntimeException(e);
    }

    if (log.isTraceEnabled()) {
        log.trace("Using: " + returnValue);
    }
    return returnValue;
}

private static String getHostNameFromEmailAddress(String mailAddress) throws TextParseException {
    String parts[] = mailAddress.split("@");
    if (parts.length != 2) throw new TextParseException("Cannot parse E-Mail-Address: '" + mailAddress + "'");
    return parts[1];
}

通过 JavaMail 代码发送邮件:

public static void sendMail(String toAddress, String fromAddress, String subject, String body) throws AddressException, MessagingException {
    String smtpServer = getMXRecordsForEmailAddress(toAddress);

    // create session
    Properties props = new Properties();
    props.put("mail.smtp.host", smtpServer);
    Session session = Session.getDefaultInstance(props);

    // create message
    Message msg = new MimeMessage(session);
    msg.setFrom(new InternetAddress(fromAddress));
    msg.setRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
    msg.setSubject(subject);
    msg.setText(body);

    // send message
    Transport.send(msg);
}
于 2008-11-07T11:37:19.860 回答
3

这是完全错误的处理方式。

任何连接到互联网的人都可以使用某种“合法”的 SMTP 服务器来提交电子邮件——您的 ISP、您的办公室等。

你想利用,因为他们为你做了几件事。

1)他们接受您的信息并负责处理该信息。放下后,就不再是你的问题了。

2) 任何邮件反垃圾邮件技术均由服务器处理。更好的是,当/如果这些技术发生变化(域键有人吗?),服务器会处理它,而不是你的代码。

3) 作为该发送邮件系统的客户端,您已经拥有与该服务器通信所需的任何凭据。主要 SMTP 服务器通过身份验证、IP 范围等被锁定。

4)你不是在重新发明轮子。利用您拥有的基础设施。您是在编写应用程序还是邮件服务器?设置邮件服务器是一项通常很容易完成的日常任务。互联网上所有那些随意的“愚蠢”用户都设法设置了电子邮件。

于 2008-11-07T17:04:08.627 回答
2

不。

发送电子邮件比看起来要复杂得多。电子邮件服务器擅长(或应该擅长)可靠交付。

如果需要,设置一个单独的电子邮件服务器 - 这与在 Java 中实现一个基本相同(我怀疑你会找到用于此任务的库 - 它们基本上是完整的邮件服务器),但更简单。

于 2008-11-07T16:43:22.023 回答