开发者

How to send email in java using asynchronous API

开发者 https://www.devze.com 2023-02-16 07:00 出处:网络
I was trying to send email using simpl开发者_Python百科e method and it was very slower. and some told me to send email via Asynchronous API.

I was trying to send email using simpl开发者_Python百科e method and it was very slower. and some told me to send email via Asynchronous API.

This was my old question Email code makes the code slower in java spring MVC

can anyone guide on this what is that and how will it make sending email faster


Setup an Executor bean that uses a thread pool executor in your spring context and use it to enqueue a work item that will send the email. It will then be dispatched on a thread pool thread asynchronously and therefore your request thread will not block.


In Spring MVC we have TaskExecutor which makes sending asynchronous mails easy.

<!-- Mail sender bean -->
 <bean class="org.springframework.mail.javamail.JavaMailSenderImpl" id="mailSender">
  <property name="host"><value>mail.test.com</value></property>
         <property name="port"><value>25</value></property>
         <property name="protocol"><value>smtp</value></property>
         <property name="username"><value>no-reply@test.com</value></property>
         <property name="password"><value>pass</value></property>
         <property name="javaMailProperties">
             <props>
                 <prop key="mail.smtp.auth">true</prop>
<!--                  <prop key="mail.smtp.starttls.enable">true</prop> -->
                 <prop key="mail.smtp.quitwait">false</prop>
             </props>
         </property>
     </bean> 

<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" id="taskExecutor">
     <property name="corePoolSize" value="5"></property>
     <property name="maxPoolSize" value="10"></property>
     <property name="queueCapacity" value="40"></property>
     <property name="waitForTasksToCompleteOnShutdown" value="true"></property>
    </bean>

Your java class should look like this:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.task.TaskExecutor;
import org.springframework.mail.MailParseException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

@Service("mailService")
public class MailService {
    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private TaskExecutor taskExecutor;

    private static Log log = LogFactory.getLog(MailService.class);

 /**
  * @param text - message
  * @param from - sender email
  * @param to - receiver email
  * @param subject - subject
  * @param filePath - file to attach, could be null if file not required
  * @throws Exception
  */
 public void sendMail(final String text,  final String from, final String to, final String subject, final File file) throws Exception {
   taskExecutor.execute( new Runnable() {
   public void run() {
    try {
      sendMailSimple(text, to, subject, file.getAbsolutePath());
    } catch (Exception e) {
     e.printStackTrace();
     log.error("Failed to send email to: " + to + " reason: "+e.getMessage());
    }
   }
  });
 }

  private void sendMailSimple(String text, String from, String to, String subject, String filePath) throws Exception { 
  MimeMessage message = mailSender.createMimeMessage();
  try {
   MimeMessageHelper helper = new MimeMessageHelper(message, true);
   helper.setFrom(from);
   helper.setTo(to);
   helper.setSubject(subject);
   helper.setText(text);
   if(filePath != null){
    FileSystemResource file = new FileSystemResource(filePath);
    helper.addAttachment(file.getFilename(), file);
   }
  } catch (MessagingException e) {
    throw new MailParseException(e);
  }
  mailSender.send(message);

  if(log.isDebugEnabled()){
   log.debug("Mail was sent successfully to: " + to + " with file: "+filePath);
  }
  }
}


The Google App Engine implementation of Javamail API allows you to send mail asynchronously, but I don't know if it is feasible to embed it in a servlet. Even if it is not feasible to use GAE like this, it proves that it is possible to implement a javamail provider that does asynchronous mail sending.

Another alternative is to set up local mail service to act as a relay for your Java application. If configured correctly, this should allow you to get messages off your hands in milliseconds. It can also take care of issues such as remote mail servers being temporarily down. The downside is that you have another service to maintain, and your Java application don't get any notification of failure to deliver mail to the ultimate recipients.


If you happen to run on a Java EE 6 server (JBoss AS 6, Glassfish v3, Resin 4), you can add a simple EJB bean, mark a method with @Asynchronous and send the email from there.

E.g.

@Singleton
public class AsyncMailer {

   @Asynchronous
   public void sendMail(...) {

      // Send mail here
   }   

}
0

精彩评论

暂无评论...
验证码 换一张
取 消