上一篇文章我们用写了一个Java Mail 的Demo,相信你已经可以用那个例子来发送邮件了。但是Demo 有很多的问题。

首先每次发送需要配置的东西很多,包括发件人的邮箱和密码、smtp服务器和SMTP端口号等信息。其次,没有将发送和邮件内容相分离。按照单一职责原则,应该有且仅有一个原因引起类的变更[1]。最后一个问题是,我们的代码不仅自己用,也很可能让别人调用。别人调用的时候不想去了解邮件发送的细节,调用的人只想传尽量少的参数获得预期的效果。因此让Demo变成可以使用的代码需要我们重新设计代码的结构。

从Demo中我们可以抽象出两种类型的POJO,也就是发件人和邮件。你可能会问收件人怎么办?收件人可以跟邮件POJO放在一起吗?

仔细思考下我们就知道,邮件和收件人应该是分开的。因为如果邮件和收件人放在一起,那么就意味着我的一封邮件只能发送给特定的人了,而实际上我们会把相同的邮件发送给不同的收件人。因此收件人只要作为发送时的参数就可以了。

1.发件人POJO

此处的代码我引用了CSDN上一篇博文JAVA邮件发送的简单实现

  1. /**
  2. * @Title: MailAuthenticator
  3. * @author: ykgao
  4. * @description:
  5. * @date: 2017-10-11 下午04:55:37
  6. */
  7. import javax.mail.Authenticator;
  8. import javax.mail.PasswordAuthentication;
  9. /**
  10. * 服务器邮箱登录验证
  11. *
  12. * @author MZULE
  13. *
  14. */
  15. public class MailAuthenticator extends Authenticator {
  16. /**
  17. * 用户名(登录邮箱)
  18. */
  19. private String username;
  20. /**
  21. * 密码
  22. */
  23. private String password;
  24. /**
  25. * 初始化邮箱和密码
  26. *
  27. * @param username 邮箱
  28. * @param password 密码
  29. */
  30. public MailAuthenticator(String username, String password) {
  31. this.username = username;
  32. this.password = password;
  33. }
  34. String getPassword() {
  35. return password;
  36. }
  37. @Override
  38. protected PasswordAuthentication getPasswordAuthentication() {
  39. return new PasswordAuthentication(username, password);
  40. }
  41. String getUsername() {
  42. return username;
  43. }
  44. public void setPassword(String password) {
  45. this.password = password;
  46. }
  47. public void setUsername(String username) {
  48. this.username = username;
  49. }
  50. }

2.邮件POJO

用于存储邮件主题和内容。

  1. /**
  2. * @Title: SimpleMail
  3. * @author: ykgao
  4. * @description:
  5. * @date: 2017-10-11 下午04:56:27
  6. */
  7. public class SimpleMail {
  8. /** 邮件主题 */
  9. public String Subject;
  10. /** 邮件内容 */
  11. public String Content;
  12. /**
  13. * @return the subject
  14. */
  15. public String getSubject() {
  16. return Subject;
  17. }
  18. /**
  19. * @param subject
  20. * the subject to set
  21. */
  22. public void setSubject(String subject) {
  23. Subject = subject;
  24. }
  25. /**
  26. * @return the content
  27. */
  28. public String getContent() {
  29. return Content;
  30. }
  31. /**
  32. * @param content
  33. * the content to set
  34. */
  35. public void setContent(String content) {
  36. Content = content;
  37. }
  38. }

3.邮件发送

设计好了POJO,我们现在需要当然是发送邮件了。在Demo中我们需要配置SMTP服务器,但是我们使用邮箱发送邮件的时候并不需要填写SMTP服务器。其实SMTP服务器大多数的格式是:smtp.emailType.com。此处emailType 就是你的邮箱类型也就是@后面跟的名称。比如163邮箱就是163。不过这个方法也不是万能的,因为outlook邮箱的smtp服务器就不是这个格式,而是smtp-mail.outlook.com ,所以我单独为outlook邮箱写了个例外。

我们还需要群分邮件的功能。这个设计起来很容易,只需要一个单人发送的重载方法,其收件人的参数可以是一个List。

为了减少接口的参数个数,我们把SMTP端口默认为587。

  1. import java.io.UnsupportedEncodingException;
  2. import java.security.GeneralSecurityException;
  3. import java.util.List;
  4. import java.util.Properties;
  5. import javaMailDevelopment.SimpleMail;
  6. import javax.mail.MessagingException;
  7. import javax.mail.Session;
  8. import javax.mail.Transport;
  9. import javax.mail.internet.AddressException;
  10. import javax.mail.internet.InternetAddress;
  11. import javax.mail.internet.MimeMessage;
  12. import javax.mail.internet.MimeMessage.RecipientType;
  13. import com.sun.mail.util.MailSSLSocketFactory;
  14. /**
  15. * @Title: SimpleMailSender
  16. * @author: ykgao
  17. * @description: 邮件发送器
  18. * @date: 2017-10-11 下午04:54:50
  19. */
  20. public class SimpleMailSender {
  21. /**
  22. * 发送邮件的props文件
  23. */
  24. private final transient Properties props = System.getProperties();
  25. /**
  26. * 邮件服务器登录验证
  27. */
  28. private transient MailAuthenticator authenticator;
  29. /**
  30. * 邮箱session
  31. */
  32. private transient Session session;
  33. /**
  34. * 初始化邮件发送器
  35. *
  36. * @param smtpHostName
  37. * SMTP邮件服务器地址
  38. * @param username
  39. * 发送邮件的用户名(地址)
  40. * @param password
  41. * 发送邮件的密码
  42. */
  43. public SimpleMailSender(final String smtpHostName, final String username, final String password) {
  44. init(username, password, smtpHostName);
  45. }
  46. /**
  47. * 初始化邮件发送器
  48. *
  49. * @param username
  50. * 发送邮件的用户名(地址),并以此解析SMTP服务器地址
  51. * @param password
  52. * 发送邮件的密码
  53. */
  54. public SimpleMailSender(final String username, final String password) {
  55. // 通过邮箱地址解析出smtp服务器,对大多数邮箱都管用
  56. String smtpHostName = "smtp." + username.split("@")[1];
  57. if (username.split("@")[1].equals("outlook.com")) {
  58. smtpHostName = "smtp-mail.outlook.com";
  59. }
  60. init(username, password, smtpHostName);
  61. }
  62. /**
  63. * 初始化
  64. *
  65. * @param username
  66. * 发送邮件的用户名(地址)
  67. * @param password
  68. * 密码
  69. * @param smtpHostName
  70. * SMTP主机地址
  71. */
  72. private void init(String username, String password, String smtpHostName) {
  73. // 初始化props
  74. props.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求)
  75. props.setProperty("mail.smtp.host", smtpHostName); // 发件人的邮箱的 SMTP 服务器地址
  76. props.setProperty("mail.smtp.auth", "true"); // 需要请求认证
  77. final String smtpPort = "587";
  78. props.setProperty("mail.smtp.port", smtpPort);
  79. // props.setProperty("mail.smtp.socketFactory.class",
  80. // "javax.net.ssl.SSLSocketFactory");
  81. props.setProperty("mail.smtp.socketFactory.fallback", "false");
  82. props.setProperty("mail.smtp.starttls.enable", "true");
  83. props.setProperty("mail.smtp.socketFactory.port", smtpPort);
  84. // 验证
  85. authenticator = new MailAuthenticator(username, password);
  86. // 创建session
  87. session = Session.getInstance(props, authenticator);
  88. session.setDebug(true);
  89. }
  90. /**
  91. * 发送邮件
  92. *
  93. * @param recipient
  94. * 收件人邮箱地址
  95. * @param subject
  96. * 邮件主题
  97. * @param content
  98. * 邮件内容
  99. * @throws AddressException
  100. * @throws MessagingException
  101. * @throws UnsupportedEncodingException
  102. */
  103. public void send(String recipient, String subject, Object content) throws Exception {
  104. // 创建mime类型邮件
  105. final MimeMessage message = new MimeMessage(session);
  106. // 设置发信人
  107. message.setFrom(new InternetAddress(authenticator.getUsername()));
  108. // 设置收件人
  109. message.setRecipient(RecipientType.TO, new InternetAddress(recipient));
  110. // 设置主题
  111. message.setSubject(subject);
  112. // 设置邮件内容
  113. message.setContent(content.toString(), "text/html;charset=utf-8");
  114. // 发送
  115. Transport.send(message);
  116. }
  117. /**
  118. * 群发邮件
  119. *
  120. * @param recipients
  121. * 收件人们
  122. * @param subject
  123. * 主题
  124. * @param content
  125. * 内容
  126. * @throws AddressException
  127. * @throws MessagingException
  128. */
  129. public void send(List<String> recipients, String subject, Object content)
  130. throws AddressException, MessagingException {
  131. // 创建mime类型邮件
  132. final MimeMessage message = new MimeMessage(session);
  133. // 设置发信人
  134. message.setFrom(new InternetAddress(authenticator.getUsername()));
  135. // 设置收件人们
  136. final int num = recipients.size();
  137. InternetAddress[] addresses = new InternetAddress[num];
  138. for (int i = 0; i < num; i++) {
  139. addresses[i] = new InternetAddress(recipients.get(i));
  140. }
  141. message.setRecipients(RecipientType.TO, addresses);
  142. // 设置主题
  143. message.setSubject(subject);
  144. // 设置邮件内容
  145. message.setContent(content.toString(), "text/html;charset=utf-8");
  146. // 发送
  147. Transport.send(message);
  148. }
  149. /**
  150. * 发送邮件
  151. *
  152. * @param recipient
  153. * 收件人邮箱地址 @param mail 邮件对象 @throws AddressException @throws
  154. * MessagingException @throws
  155. */
  156. public void send(String recipient, SimpleMail mail) throws Exception {
  157. send(recipient, mail.getSubject(), mail.getContent());
  158. }
  159. /**
  160. * 群发邮件
  161. *
  162. * @param recipients
  163. * 收件人们
  164. * @param mail
  165. * 邮件对象
  166. * @throws AddressException
  167. * @throws MessagingException
  168. */
  169. public void send(List<String> recipients, SimpleMail mail) throws AddressException, MessagingException {
  170. send(recipients, mail.getSubject(), mail.getContent());
  171. }
  172. }

4.测试代码

代码写完了,现在需要测试下代码是否可行。

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. /**
  4. * @Title: testMail
  5. * @author: ykgao
  6. * @description:
  7. * @date: 2017-10-11 下午02:13:02
  8. *
  9. */
  10. public class testMail {
  11. public static void main(String[] args) throws Exception {
  12. /** 创建一个邮件发送者*/
  13. SimpleMailSender simpleMailSender=new SimpleMailSender("Example@outlook.com", "password");
  14. /** 创建一封邮件*/
  15. SimpleMail mail=new SimpleMail();
  16. mail.setContent("This is a test email.");
  17. mail.setSubject("We want to invite you to our home.");
  18. /**
  19. List<String> recipients=new ArrayList<String>();
  20. recipients.add("Example1@qq.com");
  21. recipients.add("Example2@qq.com");
  22. recipients.add("Example2@qq.com");
  23. simpleMailSender.send(recipients, mail);
  24. }
  25. }

再次感谢小瓶子的博客,我的大部分代码都是从他的博客基础上修改的。


  1. 引自《设计模式之禅》,秦小波 著 ↩︎

Java Mail 邮件发送简单封装的更多相关文章

  1. java mail邮件发送(带附件) 支持SSL

    java mail邮件发送(带附件)有三个类 MailSenderInfo.java package mail; import java.util.Properties; import java.ut ...

  2. Java Mail邮件发送的简单实现

    1.什么是java mail JAVA MAIL是利用现有的邮件账户发送邮件的工具,通过JAVA Mail的操控,让程序自动的使用设置的邮箱发送邮件. 这一机制被广泛的用在注册激活和垃圾邮件的发送等方 ...

  3. Java Mail 邮件发送Demo

    上周公司的项目要求开发邮件发送功能.自己在网上跟着教程边学边做了一下午,现在基本开发完成了.由于一个同事也想看下该怎么写,顺便学习下.所以我就写成了一遍教程,顺便巩固下邮件发送里面的内容. Demo ...

  4. 用java实现邮件发送验证码

    java实现邮件发送验证码 建议不要用qq邮箱,我使用qq邮箱直接一直给我报530错误,我一直认为我代码写的有错误或者POP3/SMTP服务没弄好.所以建议注册个别的邮箱,我就申请了个网易163邮箱瞬 ...

  5. Spring mail 邮件发送的简单实现

    package cn.taskSys.utils; import java.util.Properties; import org.springframework.mail.MailException ...

  6. 基于Java Mail 进行发送(带附件和压缩附件)的邮件

    刚进公司的training, 下面是要求: Self-study of Java Mail library:  http://www.oracle.com/technetwork/java/javam ...

  7. 【Java EE 学习 21 下】【使用java实现邮件发送、邮件验证】

    一.邮件发送 1.邮件发送使用SMTP协议或者IMAP协议,这里使用SMTP协议演示. SMTP协议使用的端口号:25 rfc821详细记载了该协议的相关信息 (1)使用telnet发送邮件(使用12 ...

  8. Java网络编程:利用Java mail包发送电子邮件

    下面代码是利用Java mail包封装了一个发送邮件的类 import java.io.File; import java.util.ArrayList; import java.util.Date; ...

  9. Java实现邮件发送

      概述 Spring Boot下面整合了邮件服务器,使用Spring Boot能够轻松实现邮件发送:整理下最近使用Spring Boot发送邮件和注意事项: Maven包依赖 <depende ...

随机推荐

  1. 学习JQuery - 10

    第四章 Styling and Animating 1. 使用内联属性修改CSS 我们知道HTML在onload时会读取css的各项值. 那么,我们能不能在之后的操作中改变css值呢? 答案是肯定的! ...

  2. 窗口大小改变绑定resize事件

    当为窗口绑定resize事件时,大部分浏览器会在每改变一个像素就触发一次resize事件.这严重影响了网站的性能. 解决方案是:利用settimeout方法为事件发触发的方法设置延迟执行的时间. 实现 ...

  3. vux报错 this指针问题

    报错: 代码: 结果:取不到this.tishi,不明白为什么在请求内部会取不到这个值. 分析:this可能有问题 解决: 结果: 这样就能取到this.tishi的值了. 总结: methods:{ ...

  4. fastcgi_param解释

    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;#脚本文件请求的路径 fastcgi_param QUERY_STRI ...

  5. backup与recover

    完全恢复: 1.关闭DB2.拷贝文件3.启动DB.<出错>startup mount4.recover database until cancel using backup control ...

  6. 河南省第七届ACM程序设计大赛总结

    省赛总结 首先说说比赛时的情况吧,刚开始的时候我的任务就是翻译英文题目,找出比较水的题目,他们两个直接找中文水题切,其实每次比赛我们都是这样配合的,由于他们的判题系统一开始存在问题,交的正确的代码给判 ...

  7. [Android Tips] 32. 解决 Android Device Monitor 在 Mac OS X 卡住

    Alternatively you can keep latest jdk and update swt used by monitor: get updated swt: https://www.e ...

  8. JS将阿拉伯数字转为钱

     function DX(n) {         if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(n))             return "数据非法" ...

  9. CH1809匹配统计【KMP】

    1809 匹配统计 0x18「基本数据结构」练习 描述 阿轩在纸上写了两个字符串,分别记为A和B.利用在数据结构与算法课上学到的知识,他很容易地求出了“字符串A从任意位置开始的后缀子串”与“字符串B” ...

  10. 虚拟机中CentoOs配置ip且连网

    1.修改"VMware Network Adapter VMnet8",配置IP 2.打开虚拟机,"编辑" => "虚拟网络编辑器", ...