Led & Sustained by

G2one Logo

Developed with

Intellij

Powered by

Spring

A simple EmailerService

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 that Grails provides for such things:

spring/resources.xml
<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>

or the equivalent bean definition in resources.groovy:

spring/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'
}

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

grails-app/services/EmailerService.groovy
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:

grails-app/controllers/TestEmailsController.groovy
/**
 * 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.

</