title: Send Mail using Spring MVC
body: <p>I have a custom MailDto object in which I set the to,cc, bCc  field and send it using RestTemplate to Spring MVC controller 
  as below</p>
  
  <pre><code>@RequestMapping(value = "/SendMail"  )
      public ResponseEntity&lt;String&gt; SendMail( @RequestBody MailMessageDto mailDto)
              throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
  </code></pre>
  
  <p>From the controller I invoke the <strong>Gateway</strong> (Spring integration).     The Gateway has a method public void sendMail(MailMessageDto    mailDto).  The gateway channel invokes a transformer which converts    the mailDto to MimeMessageHelper object. The mimeMessageHelper object    is sent as a mail using a mailoutbound adapter. Now I want to send a    mail using RestTemplate but with a attachment using same MailDto.</p>
  
  <p>Problem is when I am changing the the Gateway and Transformmer method signature to accomodate the Multipart file and MailMessageDto which I will convert to MimeMessageHelper object in transform method spring integration is not able to understand the transform method.</p>
  
  <p><strong>I am wondering the what should be the signature of the controller method and how to declare the Transformer transform method in xml.</strong></p>
  
  <pre><code>The mail-context file
  &lt;context:component-scan base-package="com.infra.mail,com.infra.audit " /&gt;  
      &lt;mvc:annotation-driven /&gt;  
  
      &lt;!-- &lt;context:property-placeholder 
  location="classpath:/mail.properties" ignore-unresolvable="true" /&gt; --&gt;
  
      &lt;bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"&gt;
          &lt;property name="host" value="${mail.host}"/&gt;
          &lt;property name="port" value="${mail.port}"/&gt;
          &lt;property name="username" value="${mail.username}"/&gt;
          &lt;property name="password" value="${mail.password}"/&gt;
          &lt;property name="defaultEncoding" value="UTF-8"/&gt; 
          &lt;property name="javaMailProperties"&gt;
              &lt;props&gt;
                  &lt;!-- Use SMTP transport protocol --&gt;
                  &lt;prop key="mail.transport.protocol"&gt;smtp&lt;/prop&gt;
                  &lt;!-- Use SMTP-AUTH to authenticate to SMTP server --&gt;
                  &lt;prop key="mail.smtp.auth"&gt;true&lt;/prop&gt;
                  &lt;!-- Use TLS to encrypt communication with SMTP server --&gt;
                  &lt;prop key="mail.smtp.starttls.enable"&gt;false&lt;/prop&gt;
                  &lt;prop key="mail.debug"&gt;true&lt;/prop&gt;
              &lt;/props&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  
  
  
  
       &lt;int:channel id="xfromMailChannel"&gt;
      &lt;int:queue/&gt; 
      &lt;/int:channel&gt;
  
  The Transformer file
  
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.StringTokenizer;
  
  import javax.mail.MessagingException;
  import javax.mail.internet.MimeMessage;
  
  import org.apache.log4j.Logger;
  import org.apache.velocity.app.VelocityEngine;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.mail.MailException;
  import org.springframework.mail.MailMessage;
  import org.springframework.mail.SimpleMailMessage;
  import org.springframework.mail.javamail.JavaMailSender;
  import org.springframework.mail.javamail.MimeMessageHelper;
  import org.springframework.ui.velocity.VelocityEngineUtils;
  
  
  /**
   * The Class MailMessageTransformer.
   */
  public class MailMessageTransformer {
  
  /** The velocity engine. */
  @Autowired
  private VelocityEngine velocityEngine;
  
  /** The mail sender. */
  @Autowired
  private JavaMailSender mailSender;
  
  /** The Constant LOG. */
  private static final Logger LOG = Logger.getLogger(MailMessageTransformer.class);
  
  
  
  /**
  * Transform MailMessageDto to SimpleMailMessage.
  *
  * @param mailDto the mail dto
  * @return the mail message
  */
  public MailMessage transformSimple(MailMessageDto mailDto) {
  
  LOG.debug("MailMessageTransformer.transform.MailMessageDto:::" + mailDto);
  if (mailDto == null) {
  return null;
  }
  
  if (mailDto.getEncoding() == null) {
  mailDto.setEncoding(IMailConstants.DEFAULT_ENCODING);
  }
  
  if (mailDto.getTemplateName() == null
  || !mailDto.getTemplateName().endsWith(IMailConstants.VELOCITY_TEMPLATE_EXTN)) {
  mailDto.setTemplateName(getTemplateName(mailDto.getEmailType()));
  }
  
  SimpleMailMessage message = new SimpleMailMessage();
  
  message.setFrom(mailDto.getFrom());
  message.setTo(mailDto.getTo());
  message.setSubject(mailDto.getSubject());
  message.setText(getMailContent(mailDto));
  message.setSentDate(new Date(System.currentTimeMillis()));
  
  message.setBcc(mailDto.getBcc());
  message.setCc(mailDto.getCc());
  message.setReplyTo(mailDto.getReplyTo());
  
  /*
  * if (null != mailDto.getBcc()) { message.setBcc(mailDto.getBcc()); }
  * if (null != mailDto.getBcc()) { message.setCc(mailDto.getCc()); } if
  * (null != mailDto.getReplyTo() &amp;&amp; !mailDto.getReplyTo().isEmpty()) {
  * message.setReplyTo(mailDto.getReplyTo()); }
  */
  
  LOG.debug("MailMessageTransformer.transform.message:::" + message);
  return message;
  }
  
  /**
  * Create the email content/body using velocity engine, velocity template
  * and MailMessageDto.
  *
  * @param mailDto the mail dto
  * @return the mail content
  */
  private String getMailContent(MailMessageDto mailDto) {
  Map&lt;String, Object&gt; model = getVelocityModel(mailDto);
  String mailContent = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, mailDto.getTemplateName(),
  mailDto.getEncoding(), model);
  LOG.debug("MailMessageTransformer.getMailContent.mailContent:::" + mailContent);
  return mailContent;
  }
  
  /**
  * Create the Model Map referred in velocity mail template file.
  *
  * @param mailDto the mail dto
  * @return the velocity model
  */
  private Map&lt;String, Object&gt; getVelocityModel(MailMessageDto mailDto) {
  Map&lt;String, Object&gt; model = new HashMap&lt;String, Object&gt;();
  model.put(IMailConstants.VM_USER, getUser(mailDto.getTo()));
  model.put(IMailConstants.VM_ALERT_TYPE, getAlertType(mailDto.getEmailType()));
  model.put(IMailConstants.VM_CONTENT, mailDto.getText());
  return model;
  }
  
  /**
  * Fetch the user (receients) name from MailMessageDto. This is referred in
  * velocity template file. Currently from TO email list. Can be changed to
  * look up user store if future
  *
  * @param toList the to list
  * @return the user
  */
  private String getUser(String[] toList) {
  
  StringBuffer user = new StringBuffer();
  
  for (String mailId : toList.clone()) {
  StringTokenizer token = new StringTokenizer(mailId, IMailConstants.EMAIL_AT);
  String to = token.nextToken();
  user.append(to).append(IMailConstants.COMMA);
  }
  
  return user.toString();
  }
  
  /**
  * Fetch the email type from MailMessageDto. This is referred in velocity
  * template file.
  *
  * @param emailType the email type
  * @return the alert type
  */
  private String getAlertType(String emailType) {
  
  String alertType = IMailConstants.SYSTEM_ALERT_TEXT;
  
  if (IMailConstants.REALTIME_EMAILTYPE.equalsIgnoreCase(emailType)) {
  alertType = IMailConstants.REALTIME_ALERT_TEXT;
  } else if (IMailConstants.OFFLINE_EMAILTYPE.equalsIgnoreCase(emailType)) {
  alertType = IMailConstants.OFFLINE_ALERT_TEXT;
  }
  
  return alertType;
  }
  
  /**
  * Fetch the name of velocity template file based on the emailType. Used by
  * Velocity Engine.
  *
  * @param emailType the email type
  * @return the template name
  */
  private String getTemplateName(String emailType) {
  
  String templateName = IMailConstants.SYSTEM_ALERT_VM;
  if (IMailConstants.REALTIME_EMAILTYPE.equalsIgnoreCase(emailType)) {
  templateName = IMailConstants.REALTIME_ALERT_VM;
  } else if (IMailConstants.OFFLINE_EMAILTYPE.equalsIgnoreCase(emailType)) {
  templateName = IMailConstants.OFFLINE_ALERT_VM;
  }
  return templateName;
  }
  
  
  /**
  * Transform MailMessageDto to MimeMessage.
  *
  * @param mailDto the mail dto
  * @return the mime message
  */
  //public MimeMessage transform(final MailMessageDto mailDto,final CommonsMultipartFile file) {
  
  public MimeMessage transform(MailMessageDto mailDto, final MultipartFile file) {
  
  
  
  LOG.debug("MailMessageTransformer.transform.mailDto:::" + mailDto);
  
  if (mailDto == null) {
  return null;
  }
  
  if (mailDto.getEncoding() == null) {
  mailDto.setEncoding(IMailConstants.DEFAULT_ENCODING);
  }
  
  if (mailDto.getTemplateName() == null
  || !mailDto.getTemplateName().endsWith(IMailConstants.VELOCITY_TEMPLATE_EXTN)) {
  mailDto.setTemplateName(getTemplateName(mailDto.getEmailType()));
  }
  
  mailDto.setText(mailDto.getText().replaceAll(System.lineSeparator(), IMailConstants.HTML_NEW_LINE));
  
  MimeMessage mimeMessage = null;
  try {
  String attachName = file.getOriginalFilename();
  mimeMessage = mailSender.createMimeMessage();
  MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
  message.setTo(mailDto.getTo());
  message.setFrom(mailDto.getFrom());
  message.setSubject(mailDto.getSubject());
  message.setText(getMailContent(mailDto), IMailConstants.TRUE);
  message.setSentDate(new Date(System.currentTimeMillis()));
  message.addAttachment(attachName, new InputStreamSource() {
  
                 @Override
                 public InputStream getInputStream() throws IOException {
                     return file.getInputStream();
                 }
             });
  
  
  if (null != mailDto.getBcc()) {
  message.setBcc(mailDto.getBcc());
  }
  if (null != mailDto.getBcc()) {
  message.setCc(mailDto.getCc());
  }
  if (null != mailDto.getReplyTo() &amp;&amp; !mailDto.getReplyTo().isEmpty()) {
  message.setReplyTo(mailDto.getReplyTo());
  }
  
  }
  catch (MessagingException msgex) {
  LOG.error("MailMessageTransformer.transformMime.Exception::: MessagingException", msgex);
  
  }
  catch (MailException mailex) {
  LOG.error("MailMessageTransformer.transformMime.Exception::: MailException ", mailex);
  
  }
  
  catch (Exception ex) {
  LOG.error("MailMessageTransformer.transformMime.Exception::: Exception", ex);
  
  }
  
  LOG.debug("MailMessageTransformer.transformMime.mimeMessage:::" + mimeMessage);
  return mimeMessage;
  }
  
  }
  
     &lt;int:channel id="outboundMailChannel"/&gt;
     &lt;int:channel id="confirmationChannel"/&gt;
  
  
  
     &lt;int:gateway id="mailGateway" service-interface="com.infra.mail.MailGateway"
        default-request-channel="xfromMailChannel" default-reply-channel="confirmationChannel" error-channel="errorChannel"&gt;
        &lt;int:method name="sendMail" payload-expression="#args[0] + #args[1]"&gt; &lt;/int:method&gt;
        &lt;/int:gateway&gt;  
  
  
     &lt;int:transformer input-channel="xfromMailChannel" output-channel="outboundMailChannel"
        ref="mailTransformer" method="transform"&gt;
          &lt;int:poller fixed-rate="60000" max-messages-per-poll="100"/&gt; 
    &lt;/int:transformer&gt;
  
     &lt;!-- Configure Mail Sender --&gt;
     &lt;int-mail:outbound-channel-adapter channel="outboundMailChannel" mail-sender="mailSender"/&gt;
  
     &lt;bean id="mailMessage" scope="prototype"&gt;
        &lt;property name="from" value="${mail.user2}"/&gt;
        &lt;property name="replyTo" value="${mail.user3}"/&gt;
     &lt;/bean&gt;
  
     &lt;bean id="mailTransformer" class="com.infra.mail.MailMessageTransformer"/&gt;
  
  &lt;/bean&gt;
  
    &lt;int:service-activator id="mailErrorChannelActivator" input-channel="errorChannel" ref="errorHandler" method="handleMailError"/&gt;  
    &lt;bean id="errorHandler" class="com.infra.audit.ErrorHandler"/&gt;
  
    &lt;int:channel-interceptor ref="infraInterceptor" pattern="*" order="3"/&gt;
    &lt;bean id="infraInterceptor" class="com.infra.audit.infraInterceptor"/&gt;
  
  
      &lt;int:channel id="sftpErrorChannel" /&gt;
  
    &lt;int:chain input-channel="xfromMailChannel" output-channel="outboundMailChannel"&gt;
  &lt;int:header-enricher&gt;
  &lt;int:error-channel ref="errorChannel" /&gt;
  &lt;/int:header-enricher&gt;
  &lt;int:poller fixed-rate="6000" max-messages-per-poll="1"/&gt; 
  &lt;/int:chain&gt;
  
  **The Gateway file**
  public interface MailGateway {
  
  /**
  * Send mail.
  *
  * @param mailDto the mail dto
  */
  
  @Gateway
  public void sendMail(MailMessageDto mailDto, MultipartFile file);
  
  }
  </code></pre>