我正在尝试将电子邮件直接发送到目标MX服务器,避免使用中继smtp服务器.有条理地,可以让名称服务器列表对dns服务器进行查询.因此,使用此类http://www.eyeasme.com/Shayne/MAILHOSTS/mailHostsLookup.html,我可以获得域的邮件交换服务器列表.
那么,一旦我有了,我该如何继续发送电子邮件?我应该使用javax.mail或如何?如果是,我该如何配置呢?
好吧,假设我们这样做了.
我们进行DNS查找以获取收件人域的MX记录.下一步是连接到该服务器并传递消息.由于作为MX运行的主机必须侦听端口25并需要接受未加密的通信,我们可以这样做:
获取MX主机名
Session
使用mail.smtp.host
set 创建到所述服务器
发邮件
我们会得到什么?
不再需要中继服务器.
我们会失去什么?
我们会慢一点(DNS-Lookup,连接世界各地的目标主机)
我们将不得不进行完整的错误处理(如果主机停机怎么办?我们什么时候重试?)
我们必须通过垃圾邮件预防来实现这一目标.所以至少我们的服务器必须解析回我们发送电子邮件的域.
结论:我不这样做.有一些替代方案(安装本地sendmail/postfix无论如何)完全能够为我们做硬SMTP工作,同时仍然简化了我们需要用Java做的工作来获取邮件.
工作实例
这是通过使用DNS解析的MX条目为gmail.com向我发送电子邮件的代码.猜猜发生了什么?被归类为垃圾邮件,因为谷歌说"它很可能不是来自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 { Hashtableenv = new Hashtable (); 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; } }