最近在web項目中,客戶端註冊時需要通過郵箱驗證,伺服器就需要向客戶端發送郵件,我把發送郵件的細節進行了簡易的封裝: 最近在web項目中,客戶端註冊時需要通過郵箱驗證,伺服器就需要向客戶端發送郵件,我把發送郵件的細節進行了簡易的封裝: 在maven中需要導入: 1 <!--Email--> 2 <d ...
最近在web項目中,客戶端註冊時需要通過郵箱驗證,伺服器就需要向客戶端發送郵件,我把發送郵件的細節進行了簡易的封裝:
在maven中需要導入:
1 <!--Email--> 2 <dependency> 3 <groupId>javax.mail</groupId> 4 <artifactId>mail</artifactId> 5 <version>1.4.7</version> 6 </dependency> 7 <dependency> 8 <groupId>javax.activation</groupId> 9 <artifactId>activation</artifactId> 10 <version>1.1.1</version> 11 </dependency>
發送方的封裝:
1 import javax.mail.Authenticator; 2 import javax.mail.PasswordAuthentication; 3 import javax.mail.Session; 4 import java.util.Properties; 5 6 public abstract class MailSession implements EmailConstant { 7 // Mail的Session對象 8 protected Session session; 9 // 發送方郵箱 10 protected String srcEmail; 11 // 發送方的授權碼(不是郵箱登陸密碼,如何獲取請百度) 12 protected String authCode; 13 14 protected MailSession(String srcEmail, String authCode) { 15 this.srcEmail = srcEmail; 16 this.authCode = authCode; 17 18 createSession(); 19 } 20 21 protected abstract void doCreateSession(Properties properties); 22 23 private void createSession() { 24 // 獲取系統屬性,並設置 25 Properties properties = System.getProperties(); 26 // 由於不同的郵箱在初始化Session時有不同的操作,需要由子類實現 27 doCreateSession(properties); 28 properties.setProperty(MAIL_AUTH, "true"); 29 30 // 生成Session對象 31 session = Session.getDefaultInstance(properties, new Authenticator() { 32 @Override 33 public PasswordAuthentication getPasswordAuthentication() { 34 return new PasswordAuthentication(srcEmail, authCode); 35 } 36 }); 37 } 38 39 public Session getSession() { 40 return session; 41 } 42 43 public String getSrcEmail() { 44 return srcEmail; 45 } 46 47 @Override 48 public String toString() { 49 return "MailSession{" + 50 "session=" + session + 51 ", srcEmail='" + srcEmail + '\'' + 52 ", authCode='" + authCode + '\'' + 53 '}'; 54 } 55 56 }
EmailConstant :
1 /** 2 * 需要的系統屬性 3 **/ 4 public interface EmailConstant { 5 String HOST_QQ = "smtp.qq.com"; 6 String HOST_163 = "smtp.163.com"; 7 String MAIL_HOST = "mail.smtp.host"; 8 String MAIL_AUTH = "mail.smtp.auth"; 9 String MAIL_SSL_ENABLE = "mail.smtp.ssl.enable"; 10 String MAIL_SSL_SOCKET_FACTORY = "mail.smtp.ssl.socketFactory"; 11 }
163郵箱的系統設置:
1 public class WYMailSession extends MailSession { 2 3 public WYMailSession(String srcEmail, String authCode) { 4 super(srcEmail, authCode); 5 } 6 7 @Override 8 protected void doCreateSession(Properties properties) { 9 properties.setProperty(MAIL_HOST, EmailConstant.HOST_163); 10 } 11 12 }
QQ郵箱的系統設置:
1 public class QQMailSession extends MailSession { 2 3 public QQMailSession(String srcEmail, String authCode) { 4 super(srcEmail, authCode); 5 } 6 7 @Override 8 protected void doCreateSession(Properties properties) { 9 properties.setProperty(MAIL_HOST, EmailConstant.HOST_QQ); 10 11 try { 12 MailSSLSocketFactory mailSSLSocketFactory = new MailSSLSocketFactory(); 13 mailSSLSocketFactory.setTrustAllHosts(true); 14 properties.put(MAIL_SSL_ENABLE, "true"); 15 properties.put(MAIL_SSL_SOCKET_FACTORY, mailSSLSocketFactory); 16 } catch (GeneralSecurityException e) { 17 e.printStackTrace(); 18 } 19 } 20 21 }
發送的郵件封裝:
1 public class MailMessage { 2 // 接收方郵箱 3 private String tagEmail; 4 // 主題 5 private String subJect; 6 // 內容 7 private String content; 8 9 public MailMessage(String tagEmail, String subJect, String content) { 10 this.tagEmail = tagEmail; 11 this.subJect = subJect; 12 this.content = content; 13 } 14 15 public String getTagEmail() { 16 return tagEmail; 17 } 18 19 public String getSubJect() { 20 return subJect; 21 } 22 23 public String getContent() { 24 return content; 25 } 26 27 @Override 28 public String toString() { 29 return "MailMessage{" + 30 "tagEmail='" + tagEmail + '\'' + 31 ", subJect='" + subJect + '\'' + 32 ", content='" + content + '\'' + 33 '}'; 34 } 35 36 }
發送部分:
1 import com.zc.util.logger.Logger; 2 import com.zc.util.logger.LoggerFactory; 3 4 import javax.mail.Message; 5 import javax.mail.MessagingException; 6 import javax.mail.Transport; 7 import javax.mail.internet.InternetAddress; 8 import javax.mail.internet.MimeMessage; 9 import java.util.Queue; 10 import java.util.concurrent.ConcurrentLinkedQueue; 11 import java.util.concurrent.Executor; 12 13 public class MailSender { 14 15 private static final Logger LOGGER = LoggerFactory.getLogger(MailSender.class); 16 // 這個隊列是有在多個發送方的情況下,可以輪流發送 17 private final Queue<MailSession> queue = new ConcurrentLinkedQueue<>(); 18 // 使用線程池,讓線程去完成發送 19 private final Executor executor; 20 21 public MailSender(Executor executor) { 22 this.executor = executor; 23 } 24 // 指定發送方,發送郵件 25 public void sendTo(MailSession mailSession, MailMessage mailMessage) { 26 if (mailSession == null) { 27 String msg = "MailSender sendTo(), mailSession can not null!"; 28 if (LOGGER.isErrorEnabled()) { 29 LOGGER.error(msg); 30 } 31 throw new NullPointerException(msg); 32 } 33 34 if (!queue.contains(mailSession)) { 35 addSender(mailSession); 36 } 37 38 executor.execute(new Runnable() { 39 @Override 40 public void run() { 41 Message message = new MimeMessage(mailSession.getSession()); 42 try { 43 message.setFrom(new InternetAddress(mailSession.getSrcEmail())); 44 // 設置接收人 45 message.addRecipient(Message.RecipientType.TO, 46 new InternetAddress(mailMessage.getTagEmail())); 47 // 設置郵件主題 48 message.setSubject(mailMessage.getSubJect()); 49 // 設置郵件內容 50 message.setContent(mailMessage.getContent(), "text/html;charset=UTF-8"); 51 // 發送郵件 52 Transport.send(message); 53 54 if (LOGGER.isInfoEnabled()) { 55 LOGGER.info("MailSender [thread:" + Thread.currentThread().getName() 56 + "] send email[" 57 + "from: " + mailSession.getSrcEmail() 58 + ", to: " + mailMessage.getTagEmail() 59 + ", subject: " + mailMessage.getSubJect() 60 + ", content: " + mailMessage.getContent() 61 + "]"); 62 } 63 } catch (MessagingException e) { 64 e.printStackTrace(); 65 } 66 67 } 68 }); 69 } 70 // 未指定發送方,由隊列輪流發送 71 public void sendTo(MailMessage mailMessage) { 72 if (mailMessage == null) { 73 String msg = "MailSender sendTo(), mailMessage not defined!"; 74 if (LOGGER.isErrorEnabled()) { 75 LOGGER.error(msg); 76 } 77 throw new NullPointerException(msg); 78 } 79 80 MailSession mailSession = queue.poll(); 81 queue.add(mailSession); 82 83 sendTo(mailSession, mailMessage); 84 } 85 86 public void addSender(MailSession mailSession) { 87 if (mailSession == null) { 88 String msg = "MailSender addSender(), sender not defined!"; 89 if (LOGGER.isErrorEnabled()) { 90 LOGGER.error(msg); 91 } 92 throw new NullPointerException(msg); 93 } 94 95 queue.add(mailSession); 96 97 if (LOGGER.isInfoEnabled()) { 98 LOGGER.info("MailSender add sender:[" + mailSession + "]"); 99 } 100 } 101 102 public MailSession removeSender(MailSession mailSession) { 103 if (queue.remove(mailSession)) { 104 if (LOGGER.isInfoEnabled()) { 105 LOGGER.info("MailSender remove sender:[" + mailSession + "]"); 106 } 107 } 108 109 return mailSession; 110 } 111 112 }
測試:
1 public class Demo { 2 3 public static void main(String[] args) { 4 Executor executor = Executors.newCachedThreadPool(new NamedThreadFactory("ZC_Email")); 5 MailSender sender = new MailSender(executor); 6 sender.sendTo(new QQMailSession("[email protected]", "xxxxx"), 7 new MailMessage("[email protected]", "java郵件!", "這是使用java發送的郵件!請查收")); 8 9 // TODO 記得線程池的關閉 10 } 11 12 }
日誌輸出:
1 18:24:02.871 [main] INFO com.zc.util.logger.LoggerFactory - using logger: com.zc.util.logger.slf4j.Slf4jLoggerAdapter 2 18:24:04.243 [main] INFO com.zc.util.mail.MailSender - [ZC-LOGGER] MailSender add sender:[MailSession{session=javax.mail.Session@1134affc, srcEmail='[email protected]', authCode='ijsuavtbasohbgbb'}], current host: 172.19.126.174 3 18:24:05.990 [ZC_Email-thread-1] INFO com.zc.util.mail.MailSender - [ZC-LOGGER] MailUtils [thread:ZC_Email-thread-1] send email[from: [email protected], to: [email protected], subject: java郵件!, content: 這是使用java發送的郵件!請查收], current host: 172.19.126.174
郵件截圖: