我试图使用简单的方法发送电子邮件,而且速度非常慢。有些人告诉我通过异步API发送电子邮件。
这是我的旧问题Email code makes the code slower in java spring MVC
任何人都可以指导这是什么以及如何更快地发送电子邮件
答案 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。它也是异步的。