ZTemplates email service
Has been a while since I last blogged, but I have been rather busy lately. Today I have done what I wanted to be doing a long time ago. I wrote a ztemplates service for sending out emails, using the powers of the rendering engine to create HTML emails. So I came up with the following service (note that I wrote this for version 0.9.9.6):
public class ZEmailService implements ZIEmailService { @Override public void render(Object obj, final String from, final String[] recipients, final String subject) throws Exception { render(obj, from, recipients, subject, "text/html"); } @Override public void render(Object obj, final String from, final String[] recipients, final String subject, String mimeType) throws Exception { if(obj.getClass().isAnnotationPresent(ZEmail.class) == false) { throw new Exception("@ZEmail annotation not present on " + obj.getClass().getCanonicalName()); } final ZIRenderService renderService = ZTemplates.getRenderService(); final ZEmail emailAnnotation = obj.getClass().getAnnotation(ZEmail.class); final Properties properties = new Properties(); final String body = renderService.render(obj); properties.put("mail.smtp.host", emailAnnotation.host()); if(emailAnnotation.username() != null) { properties.put("mail.user", emailAnnotation.username()); } if(emailAnnotation.username() != null) { properties.put("mail.password", emailAnnotation.password()); } sendMail(properties, from, recipients, subject, mimeType, body); } private static void sendMail(final Properties properties, final String from, final String[] recipients, final String subject, final String mimeType, final String body) throws MessagingException { final Session session = Session.getDefaultInstance(properties, null); final Message message = new MimeMessage(session); final InternetAddress addressFrom = new InternetAddress(from); final InternetAddress[] addressTo = new InternetAddress[recipients.length]; for (int i = 0; i < recipients.length; i++) { addressTo[i] = new InternetAddress(recipients[i]); } message.setFrom(addressFrom); message.setRecipients(Message.RecipientType.TO, addressTo); message.setSubject(subject); message.setContent(body, mimeType); Transport.send(message); } }
Here is the interface:
public interface ZIEmailService extends ZIService { public void render(Object obj, final String from, final String[] recipients, final String subject) throws Exception; public void render(Object obj, final String from, final String[] recipients, final String subject, String mimeType) throws Exception; }
And the code for the @ZEmail annotation:
@Retention(RetentionPolicy.RUNTIME) public @interface ZEmail { String host() default "localhost"; String username(); String password(); }
Let’s say we have a view like:
@ZRenderer(value = ZJspRenderer.class) @ZEmail(password = "secret", host = "somehost", username = "admin") public class SomeView { @ZExpose public String someValue() { } }
As you can see the @ZEmail annotation makes it possible to set mail server settings. To actually send the mail using that view we only have to do the following:
new ZEmailService().render(new SomeView(), "from@example.org", new String[] { "to@example.org" }, "subject");
As you can see I’m not using the ServiceRepository in this example, I added the service to ztemplates myself, so I’m running a custom version. Just instantiating the service works as well.
There are of course a lot of improvements possible, but this version matches my needs. I hope someone will have some use of it.
Note: Will probably also work using other renderers, didn’t test it
Required external libraries:
- mail.jar
- activation.jar
Hope to be blogging some more soon.
Tags: email, java, ztemplates