Итак, предположим, что мы это делаем.
Мы выполняем поиск DNS для получения записей MX для домена получателя. Следующим шагом будет подключение к этому серверу и доставка сообщения. Как хозяева, работающие в MX должны слушать на порту 25 и нужно принимать незашифрованные коммуникации, мы могли бы сделать это так:
- получить имя хоста MX
- создать
Session
с mail.smtp.host
набор на указанный сервер
- отправить почта
Что мы получим?
- Больше нет необходимости в сервере ретрансляции.
Что мы потеряем?
- Мы будем медленнее (DNS-просмотр, подключение к целевому хосту по всему миру)
- Мы должны сделать полный обработка ошибок (Что делать, если хост отключен? Когда мы повторить ?)
- Нам нужно будет пройти через защиту от спама. Поэтому, по крайней мере, наш сервер должен вернуться к домену, с которого мы отправляем наши письма.
Заключение: Я этого не сделаю. Существуют альтернативы (установить локальный sendmail/postfix), которые отлично справляются с трудными SMTP-работами для нас, но при этом упрощают работу, которую мы должны выполнять на Java, чтобы получить почту на своем пути.
Рабочий примера
Вот код, который работал в отправке мне по электронной почте с помощью DNS MX записи разрешенной для gmail.com. Угадайте, что случилось? Got классифицируется как СПАМ, потому что Google сказал, что «это, скорее всего, не с января»
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("[email protected]");
message.addRecipient(RecipientType.TO, new InternetAddress("[email protected]"));
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;
}
}
Великий ответ! только одно: в строке message.setFrom («[email protected]»)); должен быть «новый интернет-адрес»? – selan
Не с JavaMail 1.5 - они добавили метод удобстваMethodFrom (String from) в MimeMessage. Но да - если вы хотите показать имя и адрес, это будет так. – Jan
Я получил это исключение: заблокировано с использованием zen.spamhaus.org, потому что мой ip теперь находится в этом черном списке? – selan