如何使用异步API在java中发送电子邮件

时间:2011-03-13 07:31:12

标签: java email spring-mvc asynchronous

我试图使用简单的方法发送电子邮件,而且速度非常慢。有些人告诉我通过异步API发送电子邮件。

这是我的旧问题Email code makes the code slower in java spring MVC

任何人都可以指导这是什么以及如何更快地发送电子邮件

5 个答案:

答案 0 :(得分:5)

在Spring上下文中设置一个使用线程池执行程序的Executor bean,并使用它来排队将发送电子邮件的工作项。然后它将异步调度到线程池线程,因此您的请求线程不会阻塞。

答案 1 :(得分:4)

在Spring MVC中,我们有 TaskExecutor 这使得发送异步邮件变得容易。

<!-- 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>

您的java类应如下所示:

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);
  }
  }
}

答案 2 :(得分:2)

Java App Engine的Google App Engine实现允许您异步发送邮件,但我不知道将其嵌入到servlet中是否可行。即使使用这样的GAE是不可行的,也证明可以实现执行异步邮件发送的javamail提供程序。

另一种方法是设置本地邮件服务,以充当Java应用程序的中继。如果配置正确,这应该允许您在几毫秒内从手中获取消息。它还可以解决远程邮件服务器暂时关闭等问题。缺点是您需要维护其他服务,并且您的Java应用程序不会收到任何向最终收件人发送邮件失败的通知。

答案 3 :(得分:0)

如果您碰巧在Java EE 6服务器(JBoss AS 6,Glassfish v3,Resin 4)上运行,您可以添加一个简单的EJB bean,使用@Asynchronous标记方法并从那里发送电子邮件。

E.g。

@Singleton
public class AsyncMailer {

   @Asynchronous
   public void sendMail(...) {

      // Send mail here
   }   

}

答案 4 :(得分:-1)

我认为您可以使用Java Google App Engine。它也是异步的。