最近在web项目中,客户端注册时需要通过邮箱验证,服务器就需要向客户端发送邮件,我把发送邮件的细节进行了简易的封装:
在maven中需要导入:
1 23 7javax.mail 41.4.7 68 javax.activation 9activation 101.1.1 11
发送方的封装:
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 Queuequeue = 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
邮件截图: