Java发送电子邮件避免smtp中继服务器并直接发送到MX服务器 [英] Java send email avoiding smtp relay server and send directly to MX server

查看:168
本文介绍了Java发送电子邮件避免smtp中继服务器并直接发送到MX服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试直接向目标MX服务器发送电子邮件,避免使用中继smtp服务器。
通常可以让名称服务器列表对dns服务器进行查询。
因此,使用此课程, http://www.eyeasme.com/Shayne /MAILHOSTS/mailHostsLookup.html ,我可以获得域名的邮件交换服务器列表。

I'm trying to send an email directly to the destination MX server, avoiding the relay smtp server. Teorically it could be possible getting the name servers list doing a query to a dns server. So, using this class, http://www.eyeasme.com/Shayne/MAILHOSTS/mailHostsLookup.html , I can get a list of the mail exchange servers of a domain.

所以,一旦我有了,我该如何继续发送电子邮件?我应该使用javax.mail或如何?如果是,我应该如何配置它?

So, once I have that, how can I proceed to send the email? I should use javax.mail or how? And if is it, how I should configure it?

推荐答案

好的,假设我们这样做了。

Okay, so suppose we do that.

我们进行DNS-Lookup来获取收件人域的MX记录。下一步是连接到该服务器并传递消息。由于作为MX运行的主机必须侦听端口25并需要接受未加密的通信,我们可以这样做:

We do DNS-Lookup to fetch MX records for recipient domain. Next step would be to connect to that server and deliver the message. As hosts operating as MX have to listen on port 25 and need to accept unencrypted communication, we could do it like that:


  • 获取MX主机名称

  • 创建会话,其中 mail.smtp.host 设置为所述服务器

  • 发送邮件

  • get MX host name
  • create Session with mail.smtp.host set to said server
  • send mail

我们会获得什么?

What would we gain?


  • 不再需要中继服务器。

我们会失去什么?

What would we lose?


  • 我们会慢一点(DNS-Lookup,与世界各地目标主机的连接)

  • 我们将不得不进行完整的错误处理(如果主机停机怎么办?我们会重试吗?)

  • 我们必须通过防止垃圾邮件来实现。所以至少我们的服务器必须解析回我们发送电子邮件的域。

  • We will be slower (DNS-Lookup, connections to target host around the world)
  • We will have to do full error-handling (What if host is down? When do we retry?)
  • We will have to make it through spam prevention. So at the very least our server has to resolve back to the domain we send our emails from.

结论:我不做那。有一些替代方案(安装本地sendmail / postfix无论如何)完全能够为我们做硬SMTP工作,同时仍然简化了我们需要用Java做的工作来获取邮件。

Conclusion: I woudn't do that. There are alternatives (install local sendmail/postfix whatever) that are perfectly able to do the hard SMTP work for us while still simplifying the work we need to do in Java to get the mail on its way.

工作示例

这是通过使用DNS解析的MX条目为gmail.com向我发送电子邮件的代码。猜猜发生了什么?被归类为垃圾邮件因为谷歌说它很可能不是来自Jan

Here's code that worked in sending me an email by using DNS resolved MX entry for gmail.com. Guess what happend? Got classified as SPAM because google said "it's most likely not from Jan"

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.naming.*;
import javax.naming.directory.*;

public class DirectMail {

    public static void main(String[] args) {
        try {
            String[] mx = getMX("gmail.com");
            for(String mxx : mx) {
                System.out.println("MX: " + mxx);
            }
            Properties props = new Properties();
            props.setProperty("mail.smtp.host", mx[0]);
            props.setProperty("mail.debug", "true");
            Session session = Session.getInstance(props);
            MimeMessage message = new MimeMessage(session);
            message.setFrom("XXXXXXXXXXXXXXXXXXXX@gmail.com");
            message.addRecipient(RecipientType.TO, new InternetAddress("XXXXXXXXXXXXXXXXXXXX@gmail.com"));
            message.setSubject("SMTP Test");
            message.setText("Hi Jan");
            Transport.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String[] getMX(String domainName) throws NamingException {
        Hashtable<String, Object> env = new Hashtable<String, Object>();

        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
        env.put(Context.PROVIDER_URL, "dns:");

        DirContext ctx = new InitialDirContext(env);
        Attributes attribute = ctx.getAttributes(domainName, new String[] {"MX"});
        Attribute attributeMX = attribute.get("MX");
        // if there are no MX RRs then default to domainName (see: RFC 974)
        if (attributeMX == null) {
            return (new String[] {domainName});
        }

        // split MX RRs into Preference Values(pvhn[0]) and Host Names(pvhn[1])
        String[][] pvhn = new String[attributeMX.size()][2];
        for (int i = 0; i < attributeMX.size(); i++) {
            pvhn[i] = ("" + attributeMX.get(i)).split("\\s+");
        }

        // sort the MX RRs by RR value (lower is preferred)
        Arrays.sort(pvhn, (o1, o2) -> Integer.parseInt(o1[0]) - Integer.parseInt(o2[0]));

        String[] sortedHostNames = new String[pvhn.length];
        for (int i = 0; i < pvhn.length; i++) {
            sortedHostNames[i] = pvhn[i][1].endsWith(".") ? 
                pvhn[i][1].substring(0, pvhn[i][1].length() - 1) : pvhn[i][1];
        }
        return sortedHostNames;     
    }
}

这篇关于Java发送电子邮件避免smtp中继服务器并直接发送到MX服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆