Spring emails: using Thymeleaf and Velocity
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Fri, 25 Mar 2016 21:10:41 +0000 (22:10 +0100)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Fri, 25 Mar 2016 21:10:41 +0000 (22:10 +0100)
SpringJava/Emails/spring-emails-web-client/pom.xml
SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerServiceImpl.java [deleted file]
SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerThymeleafServiceImpl.java [new file with mode: 0644]
SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerVelocityServiceImpl.java [new file with mode: 0644]
SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/webservices/rest/controller/EmailController.java
SpringJava/Emails/spring-emails-web-client/src/main/resources/email/email-template-thymeleaf.html [new file with mode: 0644]
SpringJava/Emails/spring-emails-web-client/src/main/resources/email/email-template.vm
SpringJava/Emails/spring-emails-web-client/src/main/resources/spring-configuration/spring-configuration.xml
SpringJava/Emails/spring-emails/pom.xml

index bf5ac7e..5dd948c 100644 (file)
                        <artifactId>hibernate-validator</artifactId>
                </dependency>
 
+               <!--  Required dependency for Thymeleaf -->
+               <dependency>
+               <groupId>org.thymeleaf</groupId>
+               <artifactId>thymeleaf</artifactId>
+               </dependency>
+                       <dependency>
+               <groupId>org.thymeleaf</groupId>
+               <artifactId>thymeleaf-spring4</artifactId>
+               </dependency>
 
                <!-- Unitary and integration tests -->
                <dependency>
diff --git a/SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerServiceImpl.java b/SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerServiceImpl.java
deleted file mode 100644 (file)
index da9f4bf..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.spring.emails.services.impl;
-
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.velocity.app.VelocityEngine;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.MessageSource;
-import org.springframework.stereotype.Service;
-import org.springframework.ui.velocity.VelocityEngineUtils;
-
-import de.spring.emails.services.EmailMakerService;
-
-
-@Service("emailMakerService")
-public class EmailMakerServiceImpl implements EmailMakerService {
-       private static final String TEMPLATES_DEFAULT_EXTENSION = ".vm";
-       private static final String TEMPLATES_DEFAULT_PATH = "email/";
-       private static final String EMAIL_CONTENT_ENCODING = "UTF-8";
-       
-    private final VelocityEngine velocityEngine;
-       private final MessageSource messageSource;
-
-       @Autowired
-    public EmailMakerServiceImpl(VelocityEngine velocityEngine, MessageSource messageSource) {
-       this.velocityEngine = velocityEngine;
-       this.messageSource = messageSource;
-    }
-
-       @Override
-       public String emailMaker(Map<String, String> text, String templateName, Locale locale) {
-               final String templateLocation = TEMPLATES_DEFAULT_PATH + templateName + TEMPLATES_DEFAULT_EXTENSION;
-               final Map<String, Object> model = new HashMap<>();
-               model.put("text", text);
-               model.put("messageSource", messageSource);
-               model.put("locale", locale);
-
-               return VelocityEngineUtils.mergeTemplateIntoString(
-                               velocityEngine, templateLocation, EMAIL_CONTENT_ENCODING, model);
-       }
-
-       @Override
-       public String getSubject(String code, Locale locale, Object... args) {
-               return messageSource.getMessage(code, args, locale);
-       }
-
-}
diff --git a/SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerThymeleafServiceImpl.java b/SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerThymeleafServiceImpl.java
new file mode 100644 (file)
index 0000000..97f710f
--- /dev/null
@@ -0,0 +1,44 @@
+package de.spring.emails.services.impl;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.MessageSource;
+import org.springframework.stereotype.Service;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.context.Context;
+
+import de.spring.emails.services.EmailMakerService;
+
+@Service("emailMakerThymeleafService")
+public class EmailMakerThymeleafServiceImpl implements EmailMakerService {
+       private final TemplateEngine templateEngine;
+       private final MessageSource messageSource;
+
+       @Autowired
+       public EmailMakerThymeleafServiceImpl(TemplateEngine templateEngine, MessageSource messageSource) {
+               this.templateEngine = templateEngine;
+               this.messageSource = messageSource;
+       }
+
+       @Override
+       public String emailMaker(Map<String, String> text, String templateLocation, Locale locale) {
+               final Context ctx = new Context(locale);
+               ctx.setVariable("name", "Gustavo Martin Morcuende");
+               ctx.setVariable("subscriptionDate", new Date());
+               ctx.setVariable("hobbies", Arrays.asList("Cinema", "Sports", "Music"));
+               ctx.setVariable("imageResourceName", "imageResourceName");
+               
+               return  this.templateEngine.process("email-inlineimage.html", ctx);
+       }
+
+       @Override
+       public String getSubject(String code, Locale locale, Object... args) {
+               return messageSource.getMessage(code, args, locale);
+       }
+
+}
+
diff --git a/SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerVelocityServiceImpl.java b/SpringJava/Emails/spring-emails-web-client/src/main/java/de/spring/emails/services/impl/EmailMakerVelocityServiceImpl.java
new file mode 100644 (file)
index 0000000..aedb305
--- /dev/null
@@ -0,0 +1,48 @@
+package de.spring.emails.services.impl;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.velocity.app.VelocityEngine;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.MessageSource;
+import org.springframework.stereotype.Service;
+import org.springframework.ui.velocity.VelocityEngineUtils;
+
+import de.spring.emails.services.EmailMakerService;
+
+
+@Service("emailMakerVelocityService")
+public class EmailMakerVelocityServiceImpl implements EmailMakerService {
+       private static final String TEMPLATES_DEFAULT_EXTENSION = ".vm";
+       private static final String TEMPLATES_DEFAULT_PATH = "email/";
+       private static final String EMAIL_CONTENT_ENCODING = "UTF-8";
+       
+    private final VelocityEngine velocityEngine;
+       private final MessageSource messageSource;
+
+       @Autowired
+    public EmailMakerVelocityServiceImpl(VelocityEngine velocityEngine, MessageSource messageSource) {
+       this.velocityEngine = velocityEngine;
+       this.messageSource = messageSource;
+    }
+
+       @Override
+       public String emailMaker(Map<String, String> text, String templateName, Locale locale) {
+               final String templateLocation = TEMPLATES_DEFAULT_PATH + templateName + TEMPLATES_DEFAULT_EXTENSION;
+               final Map<String, Object> model = new HashMap<>();
+               model.put("text", text);
+               model.put("messageSource", messageSource);
+               model.put("locale", locale);
+
+               return VelocityEngineUtils.mergeTemplateIntoString(
+                               velocityEngine, templateLocation, EMAIL_CONTENT_ENCODING, model);
+       }
+
+       @Override
+       public String getSubject(String code, Locale locale, Object... args) {
+               return messageSource.getMessage(code, args, locale);
+       }
+
+}
index 4bcc5b2..25bebd5 100644 (file)
@@ -29,25 +29,28 @@ public class EmailController {
        private static final String USER = "Gustavo Martin Morcuende";
        private static final String USER_ADDRESS = "noemail@gumartinm.name";
        private static final String TEMPLATE = "email-template";
+       private static final String LOGO = "logo";
+       private static final String LOGO_RESOURCE = "email/logo.png";
        private static final String SUBJECT_MESSAGE_KEY = "email.subject";
 
        private final EmailService emailService;
-       private final EmailMakerService emailMakerService;
+       private final EmailMakerService emailMakerVelocityService;
        
        @Autowired
-    public EmailController(EmailService emailService, EmailMakerService emailMakerService) {
+    public EmailController(EmailService emailService, EmailMakerService emailMakerVelocityService) {
                this.emailService = emailService;
-               this.emailMakerService = emailMakerService;
+               this.emailMakerVelocityService = emailMakerVelocityService;
        }
 
        @RequestMapping(method = RequestMethod.GET)
     @ResponseStatus(HttpStatus.OK)
     public void emails() throws MessagingException {
-               final String emailSubject = emailMakerService.getSubject(SUBJECT_MESSAGE_KEY, Locale.getDefault());
+               final String emailSubject = emailMakerVelocityService.getSubject(SUBJECT_MESSAGE_KEY, Locale.getDefault());
                final String emailText = doEmailText();
-               final String[] to = { USER_ADDRESS };   
                final Map<String, Resource> inline = new HashMap<>();
-               inline.put("cid:mainlogo", new ClassPathResource("email/logo.png"));
+               inline.put(LOGO, new ClassPathResource(LOGO_RESOURCE));
+               final String[] to = { USER_ADDRESS };
+
                try {
                        emailService.sendEmailAsync(to, emailSubject, emailText, true, null, inline);
                } catch (MessagingException ex) {
@@ -60,6 +63,7 @@ public class EmailController {
                final Map<String, String> text = new HashMap<>();
                text.put("user", USER);
                text.put("date", isoDateTime);
-               return emailMakerService.emailMaker(text, TEMPLATE, Locale.getDefault());
+               text.put(LOGO, LOGO);
+               return emailMakerVelocityService.emailMaker(text, TEMPLATE, Locale.getDefault());
        }
 }
diff --git a/SpringJava/Emails/spring-emails-web-client/src/main/resources/email/email-template-thymeleaf.html b/SpringJava/Emails/spring-emails-web-client/src/main/resources/email/email-template-thymeleaf.html
new file mode 100644 (file)
index 0000000..360148b
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+  <head>
+    <title th:remove="all">Thymeleaf template for HTML email</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  </head>
+  <body>
+    <p th:text="#{greeting(${name})}">
+      Hello, Peter Static!
+    </p>
+    <p th:if="${name.length() > 10}">
+      Wow! You've got a long name (more than 10 chars)!
+    </p>
+    <p>
+      You have been successfully subscribed to the <b>Fake newsletter</b> on
+      <span th:text="${#dates.format(subscriptionDate)}">28-12-2012</span>
+    </p>
+    <p>Your hobbies are:</p>
+    <ul th:remove="all-but-first">
+      <li th:each="hobby : ${hobbies}" th:text="${hobby}">Reading</li>
+      <li>Writing</li>
+      <li>Bowling</li>
+    </ul>
+    <p>
+      You can find <b>your inlined image</b> just below this text.
+    </p>
+    <p>
+      <img src="logo.png" th:src="'cid:' + ${imageResourceName}" />
+    </p>
+    <p>
+      Regards, <br />
+      <em>The Thymeleaf Team</em>
+    </p>
+  </body>
+</html>
\ No newline at end of file
index a5fc478..c432394 100644 (file)
@@ -1,4 +1,8 @@
 <html>
+       <head>
+       <title>Velocity template for HTML email</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+       </head>
        <body>
                <h1>#msg("email.header1")</h1>
                <h2>#msg("email.header2")/h2>
                <p>
                        ${text.date}
                </p>
-               <img src='cid:mainlogo'>
+                       <img src='cid:${text.logo}'>
+               <p>
+               Regards, <br />
+               <em>Gustavo Martin Morcuende</em>
+       </p>
        </body>
 </html>
\ No newline at end of file
index fa22293..5bd90ec 100644 (file)
                <property name="defaultEncoding" value="UTF-8"/>
        </bean>
 
+
+       <bean name="mailMessageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> 
+           <property name="basename"> 
+               <value>email.email-messages</value> 
+           </property> 
+           <property name="defaultEncoding" value="UTF-8"/>
+       </bean>
+       
+       <bean id="emailService"
+               class="de.spring.emails.services.impl.EmailServiceImpl">
+               <constructor-arg ref="mailSender" />
+       </bean>
+       
+       <!-- Using Velocity instead of Thymeleaf -->
        <bean id="mailVelocityEngine"
                class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
                <property name="velocityProperties">                    
                </props>        
                </property>
        </bean>
+       <bean id="emailMakerVelocityService"
+               class="de.spring.emails.services.impl.EmailMakerVelocityServiceImpl">
+               <constructor-arg ref="mailVelocityEngine" />
+               <constructor-arg ref="mailMessageSource" />
+       </bean>
 
-       <bean name="mailMessageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> 
-           <property name="basename"> 
-               <value>email.email-messages</value> 
-           </property> 
-           <property name="defaultEncoding" value="UTF-8"/>
+
+
+       <!-- Using Thymeleaf instead of Velocity -->
+       <bean id="thymeleafTemplateResolver"
+               class="org.thymeleaf.templateresolver.ClassLoaderTemplateResolver">
+               <property name="prefix" value="/email/" />
+               <property name="suffix" value=".html" />
+               <property name="templateMode" value="HTML" />
        </bean>
-       
-       <bean id="emailService"
-               class="de.spring.emails.services.impl.EmailServiceImpl">
-               <constructor-arg ref="mailSender" />
+       <bean id="thymeleafTemplateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
+               <property name="templateResolver" ref="thymeleafTemplateResolver" />
        </bean>
-       
-       <bean id="emailMakerService"
-               class="de.spring.emails.services.impl.EmailMakerServiceImpl">
-               <constructor-arg ref="mailVelocityEngine" />
+       <bean id="emailMakerThymeleafService"
+               class="de.spring.emails.services.impl.EmailMakerThymeleafServiceImpl">
+               <constructor-arg ref="thymeleafTemplateEngine" />
                <constructor-arg ref="mailMessageSource" />
        </bean>
-       
+
 </beans>
index bf9c1a3..7f8db54 100644 (file)
 
 
 
-                       <!-- Required dependency for VelocityEngineUtils -->
+                       <!-- Required dependencies for VelocityEngineUtils -->
                        <dependency>
                                <groupId>org.springframework</groupId>
                                <artifactId>spring-context-support</artifactId>
                                <artifactId>velocity-tools</artifactId>
                                <version>2.0-beta1</version>
                        </dependency>
+                       
+                       <!--  Required dependency for Thymeleaf -->
+                       <dependency>
+                       <groupId>org.thymeleaf</groupId>
+                       <artifactId>thymeleaf</artifactId>
+                       <version>3.0.0.BETA02</version>
+                       </dependency>
+                       <dependency>
+                       <groupId>org.thymeleaf</groupId>
+                       <artifactId>thymeleaf-spring4</artifactId>
+                       <version>3.0.0.BETA02</version>
+                       </dependency>
 
                        <!-- Required dependencies for SMTP client -->
                        <dependency>