Wednesday, June 4, 2014

Sending emails with attachments

In this example, I will show you how to use Java and Spring to send an email with attachments. Here is the main class to start things off:
package com.noushin.spring.email;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import javax.mail.MessagingException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Main class to demonstrate sending an email with attachments.
 * 
 * @author nbashir
 * 
 */
public class EmailMain {

   public static void main(String[] args) {
      ApplicationContext ctx = new ClassPathXmlApplicationContext("application-context.xml");
      try {
         if (ctx != null) {
            Emailer emailer = ctx.getBean(Emailer.class);
            Collection<File> attachments = new ArrayList<File>();
            File attachment = new File("/home/nbashir/file.txt");
            attachments.add(attachment);
            emailer.sendEmail("Test Email", "Please see attached file(s).", attachments);
         }
      }
      catch (MessagingException me) {
         // TODO Auto-generated catch block
         me.printStackTrace();
      }
      catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}
And Emailer class that generates an Email message, attaches files to it, and delivers.
package com.noushin.spring.email;

import java.io.File;
import java.util.Collection;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

@Component
public class Emailer {

   @Autowired
   @Qualifier("mailSender")
   private JavaMailSender mailSender;

   @Value("${email.recipients}")
   private String emailRecipients;
   @Value("${email.from}")
   private String emailFrom;
   @Value("${email.reply.to}")
   private String emailReplyTo;

   /**
    * Send an email with attachments
    * 
    * @param subject email's subject line
    * @param body email's body
    * @param attachments list of attachments
    * 
    * @throws MessagingException 
    */
   public void sendEmail(String subject, String body, Collection<File> attachments) throws MessagingException {

      MimeMessage message = mailSender.createMimeMessage();
      MimeMessageHelper msgHelper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED);

      String[] recipients = getRecipients(emailRecipients);
      if (recipients != null) {
         for (int i = 0; i < recipients.length; i++)
            msgHelper.addTo(recipients[i]);
      }
      msgHelper.setFrom(emailFrom);
      msgHelper.setReplyTo(emailReplyTo);
      msgHelper.setSubject(subject);
      msgHelper.setText(body, true);

      if (attachments != null) {
         String filename = null;
         for (File attachment : attachments) {
            filename = attachment.getName();
            FileSystemResource res = new FileSystemResource(attachment);
            msgHelper.addAttachment(filename, res);
         }
      }

      mailSender.send(message);
   }

   /**
    * Return a list of strings
    * 
    * @param csvList a string containing a comma separated values 
    * @return a list of strings
    */
   public String[] getRecipients(String csvList) {
      String[] values = null;
      if (csvList != null) {
         values = csvList.split(",");
         for (int i = 0; i < values.length; i++)
            values[i] = values[i].trim();
      }
      return values;
   }
}
The pom file you need:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.noushin.spring</groupId>
    <artifactId>email</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>email</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.0.3.RELEASE</spring.version>
        <java.mail>1.4.7</java.mail>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>${java.mail}</version>
        </dependency>

    </dependencies>

</project>

And application context:
<?xml version="1.0" encoding="UTF-8"?>
<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"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="file:/home/nbashir/email.properties" />
    
    <!-- Activate annotation configured components -->
    <context:annotation-config />

    <!-- Scan components for annotations within the configured package -->
    <context:component-scan base-package="com.noushin.spring.email" />
        
    <!-- Email handler -->
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="${email.host}" />
        <property name="port" value="${email.port}" />
    </bean>

</beans>