日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JavaMail異步郵件發(fā)送

 大明明小珠珠 2015-10-30

      今天把之前寫的使用JavaMail異步發(fā)送郵件的demo程序貼出來。

 

      最近一段時間,發(fā)現(xiàn)新浪微博手機客戶端也開始支持異步發(fā)送信息了。不管是發(fā)微博,還是評論微博,點擊過“發(fā)送”按鈕之后,馬上會被告知“已經(jīng)進入發(fā)送隊列”,我覺得這明顯增加了用戶體驗,并且這個提升也不存在任何技術困難。這樣一種情況,比如我發(fā)一個帶圖的微博消息,在不使用wifi的情況下,上傳一個稍大些的圖片可能會耗費不少時間。假如微博客戶端不支持異步發(fā)送,也許就因為圖片的上傳,這個客戶端得卡上好半天,直到上傳完成為止。這種完全阻塞的方式,對用戶來說可不是種好的體驗。 

 

      發(fā)送郵件的時候同樣存在著類似上面的情況。整個郵件的發(fā)送過程是比較耗時的,假如使用普通的單線程串行處理方式,當并發(fā)量大時,必然帶來災難性的后果。在下面的例子中,我使用多線程的方式來解決這個問題,使得郵件支持異步發(fā)送。

 

      要支持新浪微博的異步發(fā)送,可以使用多線程方式,也可以使用消息服務。我本身對于JMS的方式不太了解,因此選擇了一種相對熟悉和容易實現(xiàn)的方式,即每個郵件發(fā)送請求都作為一個線程任務,由線程池中的線程來處理每一個郵件發(fā)送任務。


      首先,介紹郵件的JavaBean對象Mail。很簡單,無需贅言。

 

Java代碼  收藏代碼
  1. package org.tang.financial.domain;  
  2.   
  3. import java.util.List;  
  4.   
  5. public class Mail {  
  6.     /** 
  7.      * 發(fā)送人 
  8.      */  
  9.     private String sender;  
  10.     /** 
  11.      * 收件人 
  12.      */  
  13.     private List<String> recipientsTo;  
  14.     /** 
  15.      * 抄送人 
  16.      */  
  17.     private List<String> recipientsCc;  
  18.     /** 
  19.      * 密送人 
  20.      */  
  21.     private List<String> recipientsBcc;  
  22.     /** 
  23.      * 主題 
  24.      */  
  25.     private String subject;  
  26.     /** 
  27.      * 正文 
  28.      */  
  29.     private String body;  
  30.     /** 
  31.      * 附件列表 
  32.      */  
  33.     private List<String> attachments;  
  34.       
  35.       
  36.     public String getSender() {  
  37.         return sender;  
  38.     }  
  39.     public void setSender(String sender) {  
  40.         this.sender = sender;  
  41.     }  
  42.     public List<String> getRecipientsTo() {  
  43.         return recipientsTo;  
  44.     }  
  45.     public void setRecipientsTo(List<String> recipientsTo) {  
  46.         this.recipientsTo = recipientsTo;  
  47.     }  
  48.     public List<String> getRecipientsCc() {  
  49.         return recipientsCc;  
  50.     }  
  51.     public void setRecipientsCc(List<String> recipientsCc) {  
  52.         this.recipientsCc = recipientsCc;  
  53.     }  
  54.     public List<String> getRecipientsBcc() {  
  55.         return recipientsBcc;  
  56.     }  
  57.     public void setRecipientsBcc(List<String> recipientsBcc) {  
  58.         this.recipientsBcc = recipientsBcc;  
  59.     }  
  60.     public String getSubject() {  
  61.         return subject;  
  62.     }  
  63.     public void setSubject(String subject) {  
  64.         this.subject = subject;  
  65.     }  
  66.     public String getBody() {  
  67.         return body;  
  68.     }  
  69.     public void setBody(String body) {  
  70.         this.body = body;  
  71.     }  
  72.     public List<String> getAttachments() {  
  73.         return attachments;  
  74.     }  
  75.     public void setAttachments(List<String> attachments) {  
  76.         this.attachments = attachments;  
  77.     }  
  78.       
  79. }  

 

 

      其次,是郵件發(fā)送程序當中需要用到的常量。各個常量的含義都已經(jīng)有說明,也無需贅言。

 

Java代碼  收藏代碼
  1. package org.tang.financial.mail;  
  2.   
  3. public abstract class MailProperties {  
  4.     /** 
  5.      * SMTP服務器 
  6.      */  
  7.     public static final String MAIL_SMTP_HOST = "mail.smtp.host";  
  8.     /** 
  9.      * SMTP服務器端口號 
  10.      */  
  11.     public static final String MAIL_SMTP_PORT = "mail.smtp.port";  
  12.     /** 
  13.      * 登錄SMTP服務器是否需要通過授權??蛇x值為true和false 
  14.      */  
  15.     public static final String MAIL_SMTP_AUTH = "mail.smtp.auth";  
  16.     /** 
  17.      * 登錄SMTP服務器默認郵箱賬號 
  18.      */  
  19.     public static final String MAIL_SMTP_USER = "mail.smtp.user";  
  20.     /** 
  21.      * 登錄SMTP服務器默認郵箱賬號對應密碼 
  22.      */  
  23.     public static final String MAIL_SMTP_PASSWORD = "mail.smtp.password";  
  24.     /** 
  25.      * 是否打開程序調(diào)試??蛇x值包括true和false 
  26.      */  
  27.     public static final String MAIL_DEBUG = "mail.debug";  
  28. }  
 

 

      接著,是郵件發(fā)送程序需要使用到得properties屬性配置文件。各個鍵值的含義參考上面的說明。

 

Java代碼  收藏代碼
  1. mail.smtp.host = smtp.example.com  
  2. mail.smtp.port = 25  
  3. mail.smtp.auth = true  
  4. mail.smtp.user = username@example.com  
  5. mail.smtp.password = password  
  6. mail.debug = true  
 

 

      最后,郵件發(fā)送的處理程序。

 

Java代碼  收藏代碼
  1. package org.tang.financial.service;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.util.Date;  
  6. import java.util.List;  
  7. import java.util.Properties;  
  8. import java.util.concurrent.Executor;  
  9. import java.util.concurrent.Executors;  
  10.   
  11. import javax.mail.Authenticator;  
  12. import javax.mail.Message;  
  13. import javax.mail.MessagingException;  
  14. import javax.mail.Multipart;  
  15. import javax.mail.PasswordAuthentication;  
  16. import javax.mail.Session;  
  17. import javax.mail.Transport;  
  18. import javax.mail.internet.AddressException;  
  19. import javax.mail.internet.InternetAddress;  
  20. import javax.mail.internet.MimeBodyPart;  
  21. import javax.mail.internet.MimeMessage;  
  22. import javax.mail.internet.MimeMultipart;  
  23.   
  24. import org.apache.commons.logging.Log;  
  25. import org.apache.commons.logging.LogFactory;  
  26. import org.springframework.stereotype.Component;  
  27. import org.tang.financial.domain.Mail;  
  28. import org.tang.financial.mail.MailProperties;  
  29. import org.tang.financial.util.CollectionUtils;  
  30. import org.tang.financial.util.StringUtils;  
  31.   
  32. @Component  
  33. public class MailService {  
  34.     private static Log logger = LogFactory.getLog(MailService.class);  
  35.     private static final String MAIL_PROPERTIE_NAME = "JavaMail.properties";  
  36.     private static Properties mailPro = new Properties();  
  37.     private static Executor executor = Executors.newFixedThreadPool(10);  
  38.   
  39.     static {  
  40.         //初始化,讀取屬性文件的過程  
  41.         InputStream in = null;  
  42.         try {  
  43.             in = MailService.class.getResourceAsStream(MAIL_PROPERTIE_NAME);  
  44.             mailPro.load(in);  
  45.         } catch (IOException e) {  
  46.             if (logger.isErrorEnabled()) {  
  47.                 logger.error(e);  
  48.             }  
  49.         } finally {  
  50.             if (in != null) {  
  51.                 try {  
  52.                     in.close();  
  53.                 } catch (IOException e) {  
  54.                     if (logger.isErrorEnabled()) {  
  55.                         logger.error(e);  
  56.                     }  
  57.                 }  
  58.             }  
  59.         }  
  60.   
  61.     }  
  62.   
  63.     public boolean sendMail(final Mail mail) {  
  64.         if(mail == null){  
  65.             return false;  
  66.         }  
  67.         //創(chuàng)建郵件發(fā)送任務  
  68.         Runnable task = new Runnable() {  
  69.             @Override  
  70.             public void run() {  
  71.                 final String username = mailPro.getProperty(MailProperties.MAIL_SMTP_USER);  
  72.                 final String password = mailPro.getProperty(MailProperties.MAIL_SMTP_PASSWORD);  
  73.                 //創(chuàng)建發(fā)送郵件的會話  
  74.                 Session session = Session.getDefaultInstance(mailPro, new Authenticator() {  
  75.                             protected PasswordAuthentication getPasswordAuthentication() {  
  76.                                 return new PasswordAuthentication(username, password);  
  77.                             }  
  78.                         });  
  79.                   
  80.                 try {  
  81.                     //創(chuàng)建郵件消息  
  82.                     MimeMessage msg = new MimeMessage(session);  
  83.                     //設置郵件發(fā)送人  
  84.                     msg.setFrom(new InternetAddress(StringUtils.isEmpty(mail  
  85.                             .getSender()) ? mailPro  
  86.                             .getProperty(MailProperties.MAIL_SMTP_USER) : mail  
  87.                             .getSender()));  
  88.                     //分別設置郵件的收件人、抄送人和密送人  
  89.                     msg.setRecipients(Message.RecipientType.TO, strListToInternetAddresses(mail.getRecipientsTo()));  
  90.                     msg.setRecipients(Message.RecipientType.CC, strListToInternetAddresses(mail.getRecipientsCc()));  
  91.                     msg.setRecipients(Message.RecipientType.BCC, strListToInternetAddresses(mail.getRecipientsBcc()));  
  92.                     //設置郵件主題  
  93.                     msg.setSubject(mail.getSubject());  
  94.                       
  95.                     Multipart mp = new MimeMultipart();  
  96.                       
  97.                     //創(chuàng)建郵件主體內(nèi)容  
  98.                     MimeBodyPart mbp1 = new MimeBodyPart();  
  99.                     mbp1.setText(mail.getBody());  
  100.                     mp.addBodyPart(mbp1);  
  101.                       
  102.                     if(!CollectionUtils.isEmpty(mail.getAttachments())){  
  103.                         //循環(huán)添加郵件附件  
  104.                         MimeBodyPart attach = null;  
  105.                         for(String path : mail.getAttachments()){  
  106.                             attach = new MimeBodyPart();  
  107.                             try {  
  108.                                 attach.attachFile(path);  
  109.                                 mp.addBodyPart(attach);  
  110.                             } catch (IOException e) {  
  111.                                 if (logger.isErrorEnabled()) {  
  112.                                     logger.error(e);  
  113.                                 }  
  114.                             }  
  115.   
  116.                         }  
  117.                     }  
  118.                       
  119.                     msg.setContent(mp);  
  120.                     msg.setSentDate(new Date());  
  121.                       
  122.                     //郵件開始發(fā)送  
  123.                     Transport.send(msg);  
  124.                 } catch (AddressException e) {  
  125.                     if (logger.isErrorEnabled()) {  
  126.                         logger.error(e);  
  127.                     }  
  128.                 } catch (MessagingException e) {  
  129.                     if (logger.isErrorEnabled()) {  
  130.                         logger.error(e);  
  131.                     }  
  132.                 }  
  133.                   
  134.                   
  135.             }  
  136.   
  137.         };  
  138.         //使用Executor框架的線程池執(zhí)行郵件發(fā)送任務  
  139.         executor.execute(task);  
  140.         return true;  
  141.     }  
  142.       
  143.     /** 
  144.      * 將列表中的字符串轉(zhuǎn)換成InternetAddress對象 
  145.      * @param list 郵件字符串地址列表 
  146.      * @return InternetAddress對象數(shù)組 
  147.      */  
  148.     private InternetAddress[] strListToInternetAddresses(List<String> list) {  
  149.         if (list == null || list.isEmpty()) {  
  150.             return null;  
  151.         }  
  152.         int size = list.size();  
  153.         InternetAddress[] arr = new InternetAddress[size];  
  154.         for (int i = 0; i < size; i++) {  
  155.             try {  
  156.                 arr[i] = new InternetAddress(list.get(i));  
  157.             } catch (AddressException e) {  
  158.                 e.printStackTrace();  
  159.             }  
  160.         }  
  161.         return arr;  
  162.     }  
  163.   
  164. }  
 

 

 

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約