Reputation: 25525
I would like to create a utility method in my app that accepts an email message as an argument and knows how to send it. This utility method would be responsible for knowing which SMTP server to use what credentials it should use to connect to it.
The problem that I'm running into with javax.mail
is that the javax.mail.Message
class and the javax.mail.MimeMessage
class expect a javax.mail.Session
object as an argument to the constructor. So I can't have a method signature like
private static void sendMail(javax.mail.Message);
because my client classes won't be able to constuct the Message without all the details that I'm trying to abstract away. They would have to know how to create a Session by connecting to the mail server.
Is there a way to create a Message without a session, or alternatively a class that encapsulates an email message that doesn't require a session?
Upvotes: 8
Views: 9862
Reputation: 11045
The MimeMessage
class will accept a null session. If you create such a message, Transport.send
may not be able to send your MimeMessage
To workaround that you just have to manage your own session and transport objects then use the non-static Transport.sendMessage
method.
public void forward(Session session, Message m) throws MessagingException {
Address[] all = m.getAllRecipients();
if (all == null) { //Don't pass null to sendMessage.
all = new InternetAddress[0];
}
Transport t;
try {
// Session properties 'mail.transport.protocol.rfc822'
// and 'mail.transport.protocol' can be used to change
// between SMTP or SMTPS.
if (all.length != 0) {
t = session.getTransport(all[0]);
} else {
t = session.getTransport();
}
} catch (NoSuchProviderException punt) {
try {
t = session.getTransport("smtp"); //Just a guess.
} catch (NoSuchProviderException fail) {
if (fail.setNextException(punt)) {
throw fail;
} else {
punt.setNextException(fail);
throw punt;
}
}
}
m.saveChanges(); //Computes additional headers.
t.connect("host", 25, "user", "pass"); //Or use one of the many other connect method overloads.
try {
t.sendMessage(m, all);
} finally {
try {
t.close();
} catch (MessagingException warning) {
}
}
}
Upvotes: 9
Reputation: 51
If you are using the Spring framework / spring boot, you can inject a Spring JavaMailSenderImpl into your class, and do (obviously you would need the SMTP server properties injected into the mail sender too) :
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
You need to add the following dependency to your app for this to work:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
Upvotes: 2
Reputation: 9011
Using Apache Commons Email, any of the following code could be added to the sendMail method depending on where you want things set.
HtmlEmail email = new HtmlEmail();
//email.setDebug(debugMode);
email.setBounceAddress("[email protected]");
email.setHostName("mySMTPHost");
email.setFrom("[email protected]");
email.addTo(emailAddress);
email.addBcc("bccAddres");
email.setSubject("Your Subject");
email.setAuthentication("[email protected]", "password");
email.setSSL(true);
email.setSmtpPort(465);
email.setHtmlMsg(html);
public static void sendMail(org.apache.commons.mail.HtmlEmail email)
{
email.send();
}
Upvotes: 5
Reputation: 450
Instead of having each client create the message class on their own, have them get a message object from your utility class. Then the utility class can construct the message object with the desired session information.
Upvotes: 1