Apache Commons Email and Reusing SMTP Connections
Currently I am using Commons Email to send email messages, but I have not been able to find a way to share smtp connections between emails sent. I have code like the following:
Email email = new SimpleEmail();
email.setFrom("example@example.com");
email.addTo("example@example.com");
email.setSubject("Hello Example");
email.setMsg("Hello Example");
email.setSmtpPort(25);
email.setHostName("localhost");
email.send();
Which is very readable, but is slow when I do a large amount of messages, which I believe is the overhead of reconnecting for each message. So I profiled it with the following code and have found that using the reusing the Transport makes things about 开发者_如何学Pythonthree times faster.
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
Session mailSession = Session.getDefaultInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect("localhost", 25, null, null);
MimeMessage message = new MimeMessage(mailSession);
message.setFrom(new InternetAddress("example@example.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress("example@example.com"));
message.setSubject("Hello Example");
message.setContent("Hello Example", "text/html; charset=ISO-8859-1");
transport.sendMessage(message, message.getAllRecipients());
So I was wondering if there was a way to make Commons Email reuse an SMTP connection for multiple email sendings? I like the Commons Email API better, but the performance is kind of painful.
Thanks, Ransom
I came up with the following solution after digging into the commons source itself. This should work, but there may be better solutions I do not know of
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
Session mailSession = Session.getDefaultInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect("localhost", 25, null, null);
Email email = new SimpleEmail();
email.setFrom("example@example.com");
email.addTo("example@example.com");
email.setSubject("Hello Example");
email.setMsg("Hello Example");
email.setHostName("localhost"); // buildMimeMessage call below freaks out without this
// dug into the internals of commons email
// basically send() is buildMimeMessage() + Transport.send(message)
// so rather than using Transport, reuse the one that I already have
email.buildMimeMessage();
Message m = email.getMimeMessage();
transport.sendMessage(m, m.getAllRecipients());
Could we not achieve this easier by getting the mail session from the first email using getMailSession() and putting it to all subsequent messages using setMailSession() ?
Not 100% sure what the
Please note that passing a username and password (in the case of mail authentication) will create a new mail session with a DefaultAuthenticator. This is a convience but might come unexpected. If mail authentication is used but NO username and password is supplied the implementation assumes that you have set a authenticator and will use the existing mail session (as expected).
from the javadoc means, though :-/ http://commons.apache.org/email/api-release/org/apache/commons/mail/Email.html#setMailSession%28javax.mail.Session%29
see also: https://issues.apache.org/jira/browse/EMAIL-96
not sure how to continue here...
精彩评论