public class EmailTemplate extends Object
A directory within the classpath should be created, and filled with the following files:
Concerning languages, although e.g. "subject.utf8.txt" must be present, there may also be files with names such as "subject_de.utf8.txt" files for other Locales.
One or both of the plain-text and HTML versions of the email must be present. If they are both present then a "multipart/alternative" email is sent.
The templates are Velocity templates meaning that variables like ${XYZ} can be used.
Velocity supports #foreach etc.
For variables in HTML files use $esc.html($xyz).
For unit testing, use the static method setLastBodyForTestingInsteadOfSendingEmails().
After that method has been called, no emails will be sent,
instead the method getLastBodyForTesting() may be used to retrieve the last sent plain/text email body.
This allows one to assert that particular emails would be sent, and that they contain particular text.
For testing with e.g. Litmus (tools to test your emails across the many email clients),
the facility writeHtmlPartToFile(Locale, URL, Map, File)
exists.
Emails can be written to disk as opposed to sent, in order that the real email that would be sent can be uploaded to
Litmus for testing, without any velocity template commands, and with real user data.
Writing code such as new EmailTemplate("myproject.mtpl.registration") has the disadvantage that if that package is renamed, refactoring tools will not see this string, and not rename it. Errors will result at run-time. The solution is to create a class in the directory, which calls its superclass constructor with its package name. This class is then instanciated in the client code, instead of the general EmailTemplate.
You can send attachments with your email (e.g. PDF invoices) by passing multiple EmailTemplate.Attachment objects to the send method.
Either you implement your own attachment, providing the filename, mime type and a way to get an InputStream for the bytes of the attachment,
or you can just create a EmailTemplate.ByteArrayAttachment by passing the filename, mime type and a byte[].
Concerning naming,
In the directory containing the template files:
class RegistrationEmailTemplate extends EmailTemplate {
public RegistrationEmailTemplate() {
super(RegistrationEmailTemplate.class.getPackage());
}
// other methods can be added, specific to this email template
}
In client code:
class RegistrationProcess {
public registerNewUser(InternetAddress emailAddress, Locale language, String name, ... ) {
String smtpServer = "localhost";
EmailTransaction tx = new EmailTransaction(smtpServer);
Map<String,String> params = new HashMap<String,String>();
params.put("USERNAME", name);
RegistrationEmailTemplate tpl = new RegistrationEmailTemplate();
tpl.send(tx, recipientEmailAddress, language, params);
tx.commit();
}
}
In unit test code:
class RegistrationProcessTest extends TestCase {
public testRegisterNewUser() {
EmailTemplate.setLastBodyForTestingInsteadOfSendingEmails();
new RegistrationProcess().registerNewUser("test@example.com", "Adrian");
String txt = EmailTemplate.getLastBodyForTesting();
assertTrue(txt.contains("Adrian"));
}
}
| Modifier and Type | Class and Description |
|---|---|
static interface |
EmailTemplate.Attachment |
static class |
EmailTemplate.ByteArrayAttachment |
protected class |
EmailTemplate.FileAttachmentJavamailDataSource |
static class |
EmailTemplate.FileNotFoundInEmailTemplateDirectoryException |
| Modifier and Type | Field and Description |
|---|---|
protected static String |
lastBodyForTesting |
protected String |
packageStr
For example "com.project.emailtpl.xyz"
|
protected static boolean |
setLastBodyForTestingInsteadOfSendingEmails |
| Constructor and Description |
|---|
EmailTemplate(Package pkg) |
EmailTemplate(String pkgStr) |
| Modifier and Type | Method and Description |
|---|---|
protected String |
expandVelocityTemplate(String leafNameStem,
Locale locale,
String extension,
Map<String,? extends Object> parameters)
Will find a file like "body.velocity.utf8.txt"
|
protected String |
findFile(String leafName) |
protected String |
findFile(String leafNameStem,
Locale locale,
String extension) |
static String |
getLastBodyForTesting()
Return the plain text body of the last email which has been sent; or the empty string in case no emails have been sent.
|
static javax.mail.BodyPart |
newAttachmentBodyPart(EmailTemplate.Attachment attachment) |
protected javax.mail.BodyPart |
parseHtmlBodyPart(Locale locale,
Map<String,? extends Object> parameters) |
protected javax.mail.BodyPart |
parsePlainTextBodyPart(Locale locale,
Map<String,? extends Object> parameters) |
protected String |
replaceImagesWithBaseURL(URL imageBaseUrl,
String htmlContents) |
void |
send(EmailTransaction tx,
Collection<javax.mail.internet.InternetAddress> recipientEmailAddresses,
Locale locale,
Map<String,? extends Object> parameters,
EmailTemplate.Attachment... attachments)
Send an email based on this email template.
|
void |
send(EmailTransaction tx,
javax.mail.internet.InternetAddress recipientEmailAddress,
Locale locale,
Map<String,? extends Object> parameters,
EmailTemplate.Attachment... attachments) |
static void |
setLastBodyForTestingInsteadOfSendingEmails()
Henceforth, no emails will be sent; instead the body will be recorded for inspection by
getLastBodyForTesting(). |
void |
writeHtmlPartToFile(Locale locale,
URL imageBaseUrl,
Map<String,? extends Object> parameters,
File file) |
protected String packageStr
protected static boolean setLastBodyForTestingInsteadOfSendingEmails
protected static String lastBodyForTesting
public EmailTemplate(Package pkg)
public EmailTemplate(String pkgStr)
protected String findFile(String leafName) throws EmailTemplate.FileNotFoundInEmailTemplateDirectoryException
EmailTemplate.FileNotFoundInEmailTemplateDirectoryExceptionprotected String findFile(String leafNameStem, Locale locale, String extension) throws EmailTemplate.FileNotFoundInEmailTemplateDirectoryException
extension - for example ".txt"EmailTemplate.FileNotFoundInEmailTemplateDirectoryExceptionprotected String expandVelocityTemplate(String leafNameStem, Locale locale, String extension, Map<String,? extends Object> parameters) throws EmailTemplate.FileNotFoundInEmailTemplateDirectoryException
leafNameStem - for example "body"extension - for example ".txt"EmailTemplate.FileNotFoundInEmailTemplateDirectoryExceptionprotected javax.mail.BodyPart parsePlainTextBodyPart(Locale locale, Map<String,? extends Object> parameters) throws EmailTemplate.FileNotFoundInEmailTemplateDirectoryException, javax.mail.MessagingException
EmailTemplate.FileNotFoundInEmailTemplateDirectoryExceptionjavax.mail.MessagingExceptionprotected javax.mail.BodyPart parseHtmlBodyPart(Locale locale, Map<String,? extends Object> parameters) throws EmailTemplate.FileNotFoundInEmailTemplateDirectoryException, javax.mail.MessagingException
EmailTemplate.FileNotFoundInEmailTemplateDirectoryExceptionjavax.mail.MessagingExceptionpublic static javax.mail.BodyPart newAttachmentBodyPart(EmailTemplate.Attachment attachment) throws javax.mail.MessagingException
javax.mail.MessagingExceptionpublic static void setLastBodyForTestingInsteadOfSendingEmails()
getLastBodyForTesting().public static String getLastBodyForTesting()
public void send(EmailTransaction tx, Collection<javax.mail.internet.InternetAddress> recipientEmailAddresses, Locale locale, Map<String,? extends Object> parameters, EmailTemplate.Attachment... attachments)
public void send(EmailTransaction tx, javax.mail.internet.InternetAddress recipientEmailAddress, Locale locale, Map<String,? extends Object> parameters, EmailTemplate.Attachment... attachments)
protected String replaceImagesWithBaseURL(URL imageBaseUrl, String htmlContents)
public void writeHtmlPartToFile(Locale locale, URL imageBaseUrl, Map<String,? extends Object> parameters, File file)
imageBaseUrl - images in the directory must be uploaded somewhere. They are then replaced
in the HTML with a link to that place.file - where to write the HTML toCopyright © 2003–2018. All rights reserved.