<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>
+++ /dev/null
-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);
- }
-
-}
--- /dev/null
+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);
+ }
+
+}
+
--- /dev/null
+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);
+ }
+
+}
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) {
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());
}
}
--- /dev/null
+<!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
<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
<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>
- <!-- 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>