Someone knows a mail (SMTP) delivery library for J

2019-03-10 04:21发布

问题:

I'd like to send mail without bothering with the SMTP-Server which is used for delivery.

So JavaMail API doesn't work for me because I have to specify a SMTP server to connect to.

I'd like the library to find out on its own which SMTP server is responsible for which email address by querying the MX record of the mail address domain.

I'm looking for something like Aspirin. Unfortunately I can't use Aspirin itself because the development stopped 2004 and the library fails to communicate with modern spam hardened servers correctly.

An embeddable version of James would do the task. But I haven't found documentation concerning whether this is possible.

Or does anyone know about other libraries I could use?

回答1:

This is completely the wrong way to handle this.

Anyone connected to the internet will have some kind of "legit" SMTP server available to them to take the submission of email -- your ISP, your office, etc.

You WANT to leverage because they do several things for you.

1) they take your message and the responsibility to handle that message. After you drop it off, it's not your problem anymore.

2) Any mail de-spamming technologies are handled by the server. Even better, when/if those technologies change (Domain keys anyone?), the server handles it, not your code.

3) You, as a client of that sending mail system, already have whatever credentials you need to talk to that server. Main SMTP servers are locked down via authentication, IP range, etc.

4) You're not reinventing the wheel. Leverage the infrastructure you have. Are you writing an application or a mail server? Setting up mail server is an every day task that is typically simple to do. All of those casual "dumb" users on the internet have managed to get email set up.



回答2:

One possible solution: get the MX record on your own and use JavaMail API.

You can get the MX record using the dnsjava project:

Maven2 dependency:

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

Method for MX record retrieval:

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];
}

Sending mail via JavaMail code:

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);
}


回答3:

Don't.

Sending email is much more complex than it seems. Email servers excel at (or should excel at) reliable delivery.

Set up a separate email server if you need to- that will be essentially the same as implementing one in Java (I doubt you will find libraries for this task- they would be essentially complete mail servers), but much more simpler.