SpringEmail with Velocity template date and number formatting
NOTE: Source Code available for download at the bottom of the page
What are we going to learn?
We will learn how to use Spring Email to send dynamic content emails using velocity Template. In this example we will display details of the students in html formatted email. We will use Velocity Tools to format the date and number fields.We will also include the generated html as an attachment.
What's needed?
- Maven
- JDK 1.5 or higher
- eclipse
Steps Involved
- Step 1: Update pom.xml file for the necessary jar files.
- Step 2: Create application context to be loaded by Spring.
- Add bean definition for Spring Email and Velocity Engine.
- Step 3: Create Student Model Object and create Velocity Email Template to display list of students
- Step 4: Add logic for sending emails
- Step 5: Put everything together in the main class.
Let's get started.
Create a maven project of artifact "maven-archetype-quickstart" as shown here. Remember to select the correct artifact "maven-archetype-quickstart" as shown below.
Step 1:
Update pom.xml file for the necessary jar files
.
- Spring Framework jars
- Java Mail jars
- Velocity jar
- Velocity tools jar
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-tools</artifactId> <version>2.0</version> </dependency>
Step 2:
Create application context to be loaded by Spring.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:annotation-config /> <context:component-scan base-package="com.visionjava.SpringVelocityTemplateEmail" /> <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="javaMailProperties"> <props> <prop key="mail.smtp.auth">false</prop> <prop key="mail.smtp.starttls.enable">true</prop> <prop key="mail.smtp.host">localhost</prop> <prop key="mail.smtp.port">1025</prop> </props> </property> <!-- <property name="username" value="email" /> <property name="password" value="password" /> --> </bean> <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> <property name="resourceLoaderPath" value="com/visionjava/SpringVelocityTemplateEmail/templates/" /> </bean> </beans>
property name="resourceLoaderPath" provides the resource location in the classpath.
If you want to use a location that's not in the classpath
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> <property name="velocityProperties"> <props> <prop key="resource.loader">file</prop> <prop key="file.resource.loader.class"> org.apache.velocity.runtime.resource.loader.FileResourceLoader </prop> <prop key="file.resource.loader.path">{path to template folder}</prop> <prop key="file.resource.loader.cache">false</prop> </props> </property> </bean>
Step 3:
Create Student Model Object and create Velocity Email Template to display list of students.
Student.java
package com.visionjava.SpringVelocityTemplateEmail.model; import java.util.Date; public class Student { private String firstName; private String lastName; private Date datEnrolled; private Double marksPercentage; public Student(String firstName, String lastName, Double marksPercentage, Date datEnrolled) { super(); this.firstName = firstName; this.lastName = lastName; this.datEnrolled = datEnrolled; this.marksPercentage = marksPercentage; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Date getDatEnrolled() { return datEnrolled; } public void setDatEnrolled(Date datEnrolled) { this.datEnrolled = datEnrolled; } public Double getMarksPercentage() { return marksPercentage; } public void setMarksPercentage(Double marksPercentage) { this.marksPercentage = marksPercentage; } }
emailTemplate.vm -- Velocity Template
<body> <style> .header{ background-color: Coral; text-align: center; font-size: 20px; } .tr1{ background-color: DarkSeaGreen; text-align: center; font-size: 15px; font-style: italic; } .tr2{ background-color:Thistle; text-align: center; font-size: 15px; font-style: italic; } </style> <table width="965" border="1"> <tr class="header"> <td style="width:25%">NAME</td> <td style="width:25%">AGE</td> <td style="width:25%">Marks % - After format</td> <td style="width:25%">Date Enrolled - After format</td> </tr> #set ($counter = 0) #foreach($stu in $students) #set ($counter = $counter + 1) #if ( $couter % 2 == 0) <tr class="tr1"> #else <tr class="tr2"> #end <td>$stu.firstName</td> <td>$stu.lastName</td> <td>
$stu.marksPercentage --
<font style="color:red;">
$number.format("#0.00",$stu.marksPercentage)
</font>
</td> <td>
$stu.datEnrolled --
<font style="color:red;">
$date.format('short',$stu.datEnrolled)
</font>
</td>
</tr> #end </table> </body>
Step 4:
Add logic for sending emails.
EmailSender.java
package com.visionjava.SpringVelocityTemplateEmail; import java.io.StringWriter; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.mail.internet.MimeMessage; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.NumberTool; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ByteArrayResource; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.mail.javamail.MimeMessagePreparator; import org.springframework.stereotype.Component; import com.visionjava.SpringVelocityTemplateEmail.model.Student; @Component("emailSender") public class EmailSender { @Autowired private JavaMailSender mailSender; @Autowired private VelocityEngine velocityEngine; public void sendEmail(final String to, final String from, final String subject, final List<Student> studentList) { MimeMessagePreparator preparator = new MimeMessagePreparator() { public void prepare(MimeMessage mimeMessage) throws Exception { StringWriter mergedContent = new StringWriter(); VelocityContext velocityContext = new VelocityContext(); velocityContext.put("students", studentList); velocityContext.put("date", new DateTool()); velocityContext.put("number", new NumberTool()); velocityEngine.mergeTemplate("emailTemplate.vm", "UTF-8", velocityContext, mergedContent); //Sending Message MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true); message.setTo(to); message.setFrom(from); message.setSubject(subject); message.setText(mergedContent.toString(), true); message.addAttachment("Studentdetails.html", new ByteArrayResource(mergedContent.toString().getBytes(), "Confirmation")); } }; this.mailSender.send(preparator); } }
Students, date and numbers objects are provided to the VelocityContext which can be use in the template to access the student objects and to format date.
Step 5:
Main class to invoke sendEmail in EmailSender
.
MainCaller.java
package com.visionjava.SpringVelocityTemplateEmail; import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.visionjava.SpringVelocityTemplateEmail.model.Student; public class MainCaller { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml"); EmailSender emailSender = (EmailSender)context.getBean("emailSender"); List<Student> studentList = new ArrayList<Student>(); Date date = new GregorianCalendar().getTime(); studentList.add( new Student("Amitabh", "Bachhan", 96.4563, date ) ); studentList.add( new Student("John", "Smith", 89.456, date ) ); studentList.add( new Student("Leonardo", "Decaprio", 65.34244, new GregorianCalendar().getTime() ) ); studentList.add( new Student("Kate", "Winslet", 55.90744, new GregorianCalendar().getTime() ) ); emailSender.sendEmail("test@visionjava.com", "test@visionjava.com", "Velocity Template Students", studentList); } }
Project Structure: