Last updated by 5 years ago

Page: A simple EmailerService, Version:3

A simple EmailerService

This tutorial provides some code for a simple Grails Service, "EmailerService", which allows you to send emails from your Grails applications.

The code was adapted from an example in the Spring documentation, so it also demonstrates integration with Spring-configured beans.

Of course there are plenty of alternative ways to do this kind of thing, for example, see grails-app/conf/Notifications.groovy in the simple-cms Grails sample application.

First we configure a couple of beans in the Spring config file ( grails-app/conf/spring/resources.xml )that Grails provides for such things:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host"><value>mail.maurice.uk</value></property> </bean>

<!-- You can set default email bean properties here, eg: from/to/subject --> <bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage"> <property name="from"><value>myapp@maurice.co.uk</value></property> </bean> <beans>

or the equivalent bean definition in resources.groovy:

mailSender(org.springframework.mail.javamail.JavaMailSenderImpl) {
   host = 'mail.maurice.uk'
}

// You can set default email bean properties here, eg: from/to/subject mailMessage(org.springframework.mail.SimpleMailMessage) { from = 'myapp@maurice.co.uk' }

Then copy two jar files into the application local lib: activations.jar and mail.jar. These jar files are needed by org.springframework.mail.javamail.JavaMailSenderImpl.

Next the service itself. Note that the "mailSender" and "mailMessage" properties (Spring beans) are automagically injected by Grails.

import org.springframework.mail.MailException
import org.springframework.mail.MailSender
import org.springframework.mail.SimpleMailMessage

/** * Simple service for sending emails. * * Work is planned in the Grails roadmap to implement first-class email * support, so there's no point in making this code any more sophisticated */ class EmailerService { boolean transactional = false MailSender mailSender SimpleMailMessage mailMessage // a "prototype" email instance

/** * Send a list of emails * * @param mails a list of maps */ def sendEmails(mails) { // Build the mail messages def messages = [] for (mail in mails) { // Create a thread safe "sandbox" of the message SimpleMailMessage message = new SimpleMailMessage(mailMessage) message.to = mail.to message.text = mail.text message.subject = mail.subject messages << message } // Send them all together try { println "about to send ${messages.size()} messages to:n${messages.to.join('n')}" mailSender.send(messages as SimpleMailMessage[]) } catch (MailException ex) { println "Failed to send emails" ex.printStackTrace() } } }

Finally inject the service into a controller, build some emails, and send them:
/**
 * Hit "http://localhost:8080/myapp/testEmails?to=me@somewhere.com&subject=hello+world&body=This+is+a+test" to send an email to yourself
 */
class TestEmailsController {
    EmailerService emailerService

// Send an email def index = { // Each "email" is a simple Map def email = [ to: [ params.to ], // "to" expects a List, NOT a single email address subject: params.subject, text: params.body // "text" is the email body ] // sendEmails expects a List emailerService.sendEmails([email]) render("done") } }

You can of course also declare one service as a property of another, so you can also send emails from other services in the same way.