1. 电子邮件服务器:这些邮件服务器就类似于邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中,按功能划分有两种类型
    • SMTP邮件服务器:用户替用户发送邮件和接收外面发送给本地用户的邮件
    • POP3/IMAP邮件服务器:用户帮助用户读取SMTP邮件服务器接收进来的邮件
  2. 邮件传输协议:电子邮件需要在邮件客户端和邮件服务器之间,以及两个邮件服务器之间进行邮件传递,就需遵守一定的规则
    • SMTP协议:全称为 Simple Mail Transfer Protocol,简单邮件传输协议。它定义了邮件客户端软件和SMTP邮件服务器之间,以及两台SMTP邮件服务器之间的通信规则
    • POP3协议:全称为 Post Office Protocol,邮局协议。它定义了邮件客户端软件和POP3邮件服务器的通信规则
    • IMAP协议:全称为 Internet Message Access Protocol,Internet消息访问协议,它是对POP3协议的一种扩展,也是定义了邮件客户端软件和IMAP邮件服务器的通信规则
  3. 邮件格式:邮件内容的基本格式和具体细节分别是由 RFC822 文档和 MIME 协议定义的
    • RFC822文档中定义的文件格式包括两个部分:邮件头和邮件体
    • ME协议(Multipurpose Internet Mail Extensions )用于定义复杂邮件体的格式,使邮件的内容更加多样化
  4. 邮件发送与接收流程
      • 邮件客户端软件写好一封邮件,交到SMTP的QQ邮件服务器
      • QQ邮箱会解析用户发送的邮件,判断收件地址是否是自己的账户,如果收件也是QQ邮箱,会直接存放到自己的存储空间。如果不是QQ邮箱,而是163邮箱,那么QQ邮箱会将邮件转发到163邮箱服务器,转发协议也是SMTP
      • 163邮箱服务器接收到QQ邮箱转发过来的邮件,会判断收件地址是否是自己的,如果是自己的账户,就会将QQ邮箱转发过来的邮件存放到自己的内部存储空间
      • 用户A将邮件发送了之后,通知用户B去指定的邮箱收取邮件。用户B会通过邮件客户端软件先向163邮箱服务器请求,要求收取自己的邮件
      • 163邮箱服务器收到用户B的请求后,会从自己的存储空间中取出B未收取的邮件
      • 163邮箱服务器取出用户B未收取的邮件后,将邮件发给用户B,最后三步用户B收取邮件的过程,使用的协议是POP3
  • 使用之前应该申请qq邮箱的授权码(第三方的使用时,替代密码)

  • qq邮箱邮件服务器地址和端口(smtp.qq.com 端口465或587)

  • 导入依赖

    1. <!--发送邮件的jar 1.4 版本会出现javamail.providers 文件找不见 与其他jar包中文件冲突-->
    2. <dependency>
    3. <groupId>javax.mail</groupId>
    4. <artifactId>mail</artifactId>
    5. <version>1.4.4</version>
    6. </dependency>
  1. 邮件的基本信息类

    1. @Data
    2. public class JavaMailInfo {
    3. /**
    4. * 使用java mail 发送邮件 邮件的协议有SMTP POP IMAP MIME 等 协议具体内容可自行百度 SMTP 为简单邮件传输协议 比较常用
    5. */
    6. // 邮件服务器地址
    7. private String mailSeverHost;
    8. // 邮件服务器端口
    9. private String mailServerPort;
    10. // 邮件发送者
    11. private String fromAddress;
    12. // 发送者用户名
    13. private String userName;
    14. // 发送者密码
    15. private String password;
    16. // 收件人地址
    17. private String toAddress;
    18. // 邮件主题
    19. private String subject;
    20. // 邮件内容
    21. private String content;
    22. // 图片地址集合
    23. private List<String> photoUrlList;
    24. // 附件地址集合
    25. private List<String> attachList;
    26. /**
    27. * 获取邮件会话属性 ,对邮件Session进行设置 此部分的内容可以通过加载配置文件的方式进行设置
    28. * @return
    29. */
    30. public Properties getProperties() {
    31. Properties properties = new Properties();
    32. properties.put("mail.transport.protocol", "smtp");// 连接协议
    33. properties.put("mail.smtp.host", this.mailSeverHost);// 主机名
    34. properties.put("mail.smtp.port", this.mailServerPort);// 端口号
    35. properties.put("mail.smtp.auth", "true");//设置smtp是否需要认证
    36. properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用
    37. properties.put("mail.debug", "true");// 设置是否显示debug信息 true 会在控制台显示相关信息
    38. properties.put("mail.smtp.timeout", 20000);// 超时时间
    39. return properties;
    40. }
    41. }
  2. 权限认证类

    1. @Data
    2. @NoArgsConstructor
    3. @AllArgsConstructor
    4. public class MyJavaMailAuthenticator extends Authenticator {
    5. private String userName = null;
    6. private String password = null;
    7. /**
    8. * 此类用于储存授权时使用的用户名和密码 用于构建邮件Session对象 便于需要认证时邮件Session知道需要使用哪个类验证
    9. * 以用户名、密码的方式访问那些受到保护的资源,在这里“资源”就是指邮件服务器
    10. * 自定义的类需要继承Authenticator类 重写getPasswordAuthentication() 方法 注意导包 需要使用javax.mail包下的相关类
    11. */
    12. @Override
    13. protected PasswordAuthentication getPasswordAuthentication() {
    14. return new PasswordAuthentication(this.userName, this.password);
    15. }
    16. }
  3. 发送邮件工具类

    1. public class JavaMailSendUtils {
    2. /**
    3. * 实际使用
    4. * @param args
    5. */
    6. public static void main(String[] args) {
    7. JavaMailInfo javaMailInfo = new JavaMailInfo();
    8. javaMailInfo.setMailSeverHost("smtp.qq.com");
    9. javaMailInfo.setMailServerPort("465");// 465或587(使用ssl)
    10. javaMailInfo.setFromAddress("发件人");
    11. javaMailInfo.setUserName("您邮箱用户名");
    12. javaMailInfo.setPassword("您邮箱授权码");// 密码需要使用对应邮箱的授权码授权码
    13. javaMailInfo.setToAddress("收件人");
    14. javaMailInfo.setSubject("邮件主题");
    15. javaMailInfo.setContent("邮件内容");
    16. List<String> photoUrlList = new ArrayList<>();
    17. photoUrlList.add("图片1");
    18. photoUrlList.add("图片2");
    19. javaMailInfo.setPhotoUrlList(photoUrlList);
    20. List<String> attachList = new ArrayList<>();
    21. attachList.add("附件1");
    22. attachList.add("附件2");
    23. javaMailInfo.setAttachList(attachList);
    24. sendJavaMail(javaMailInfo);
    25. }
    26. /**
    27. * 此工具类可根据邮件基本信息进行邮件的发送
    28. */
    29. /**
    30. * 发送邮件方法
    31. * @param javaMailInfo
    32. * @return
    33. */
    34. public static boolean sendJavaMail(JavaMailInfo javaMailInfo) {
    35. // 获取邮件session的相关配置参数
    36. Properties properties = javaMailInfo.getProperties();
    37. // 创建授权验证类
    38. MyJavaMailAuthenticator myJavaMailAuthenticator = new MyJavaMailAuthenticator();
    39. myJavaMailAuthenticator.setUserName(javaMailInfo.getUserName());
    40. myJavaMailAuthenticator.setPassword(javaMailInfo.getPassword());
    41. // 构建邮件Session会话对象 带不带default均可 查看源码可知 带default的是获取该类的属性 不带获取的是新创建的
    42. Session mailSession = Session.getDefaultInstance(properties, myJavaMailAuthenticator);
    43. // 开启debug properties中设置了此处就无须设置
    44. // mailSession.setDebug(true);
    45. // 邮差对象 也可使用静态方法进行发送
    46. Transport transport = null;
    47. try {
    48. // 获取消息 也就是发送的内容
    49. // Message message = createSimpleMail(mailSession, javaMailInfo);
    50. // Message message = createImageMail(mailSession, javaMailInfo);
    51. // Message message = createAttachMail(mailSession, javaMailInfo);
    52. Message message = createPhotoAndAttachMail(mailSession, javaMailInfo);
    53. // 设置规范 具体是什么规范呢? 固定写法
    54. MailcapCommandMap defaultCommandMap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
    55. defaultCommandMap.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
    56. defaultCommandMap.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
    57. defaultCommandMap.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
    58. defaultCommandMap.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
    59. defaultCommandMap.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
    60. CommandMap.setDefaultCommandMap(defaultCommandMap);
    61. // 发送邮件 Transport.send(message); 或者获取Transport对象发送
    62. transport = mailSession.getTransport();
    63. transport.connect(javaMailInfo.getUserName(), javaMailInfo.getUserName());
    64. transport.sendMessage(message, message.getAllRecipients());
    65. System.out.println("邮件发送成功");
    66. return true;
    67. } catch (MessagingException e) {
    68. e.printStackTrace();
    69. System.out.println("邮件发送失败");
    70. return false;
    71. } finally {
    72. if (null != transport) {
    73. try {
    74. transport.close();
    75. } catch (MessagingException e) {
    76. e.printStackTrace();
    77. }
    78. }
    79. }
    80. }
    81. /**
    82. * 根据邮件Session和邮件信息创建邮件内容(文本类 html)
    83. * @param mailSession
    84. * @param javaMailInfo
    85. * @return
    86. */
    87. private static Message createSimpleMail(Session mailSession, JavaMailInfo javaMailInfo) throws MessagingException {
    88. /**
    89. * Message是一 个抽象类,我们使用MimeMessage这个子类, 该类是使用MIME类型、MIME信息头的 邮箱信息
    90. * 信息头只能使用US-ASCII字符,而非ASCII字符将通过编码转换为ASCII的方式使用
    91. */
    92. // 根据邮件session创建消息对象
    93. MimeMessage mimeMessage = new MimeMessage(mailSession);
    94. // 设置发件人 setFrom 和 setReplyTo 均可 有多个发件人使用 addFroms(Address[] addresses)
    95. mimeMessage.setFrom(new InternetAddress(javaMailInfo.getFromAddress()));
    96. // 设置收件人 收件人类型 Message.RecipientType.TO(接受者) Message.RecipientType.CC(抄送着) Message.RecipientType.BCC(密送者)
    97. // setRecipients(Message.RecipientType var1, Address[] var2) 设置多个收件人
    98. mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(javaMailInfo.getToAddress()));
    99. // 设置标题
    100. mimeMessage.setSubject(javaMailInfo.getSubject(), "text/plain;charset=utf-8");
    101. // 设置内容 是文本可直接使用setText()
    102. mimeMessage.setContent(javaMailInfo.getContent(), "text/html;charset=utf-8");
    103. // 设置发送时间
    104. mimeMessage.setSentDate(new Date());
    105. mimeMessage.saveChanges();
    106. return mimeMessage;
    107. }
    108. /**
    109. * 根据邮件Session和邮件信息创建邮件内容(图片类 可多个图片)
    110. * @param mailSession
    111. * @param javaMailInfo
    112. * @return
    113. */
    114. private static Message createImageMail(Session mailSession, JavaMailInfo javaMailInfo) throws MessagingException {
    115. /**
    116. * Message表示一个邮件,messgaes.getContent()返回一个Multipart对象。一个Multipart对象包含一个或多个BodyPart对象,来组成邮件的正文部分(包括附件)
    117. * Multipart的content-type
    118. * 总体来说,MIME消息由消息头和消息体两大部分组成。现在我们关注的是MIME邮件,因此在以下的讨论中姑且称“消息”为“邮件”。
    119. * 邮件头包含了发件人、收件人、主题、时间、MIME版本、邮件内容的类型等重要信息。每条信息称为一个域,由域名后加“: ”和信息内容构成,可以是一行,较长的也可以占用多行。
    120. * 域的首行必须“顶头”写,即左边不能有空白字符(空格和制表符);续行则必须以空白字符打头,且第一个空白字符不是信息本身固有的,解码时要过滤掉。
    121. * 邮件体包含邮件的内容,它的类型由邮件头的“Content-Type”域指出。常见的简单类型有text/plain(纯文本)和text/html(超文本)。有时也会出现的multipart类型,是MIME邮件的精髓。
    122. * 邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。常见的multipart类型有三种:multipart/mixed, multipart/related和multipart/alternative。
    123. * multipart/mixed:附件。
    124. * multipart/related:内嵌资源。
    125. * multipart/alternative:纯文本与超文本共存。
    126. */
    127. MimeMessage mimeMessage = new MimeMessage(mailSession);
    128. mimeMessage.setFrom(new InternetAddress(javaMailInfo.getFromAddress()));
    129. mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(javaMailInfo.getToAddress()));
    130. mimeMessage.setSubject(javaMailInfo.getSubject(), "text/plain;charset=utf-8");
    131. List<String> photoUrlList = javaMailInfo.getPhotoUrlList();
    132. // 创建消息体 以下方式每个图片都有一个标题
    133. MimeMultipart mimeMultipart = new MimeMultipart();
    134. if (!CollectionUtils.isEmpty(photoUrlList)) {
    135. for (String photoUrl : photoUrlList) {
    136. MimeBodyPart text = new MimeBodyPart();
    137. // 设置图片标题 注意img标签的引用位置 用cid:开头
    138. String cid = UUID.randomUUID().toString();
    139. text.setContent(javaMailInfo.getContent() +"<br/><img src=\'cid:"+ cid +".jpg\'>", "text/html;charset=utf-8");
    140. // 使用数据处理器处理图片
    141. MimeBodyPart image = new MimeBodyPart();
    142. image.setDataHandler(new DataHandler(new FileDataSource(photoUrl)));
    143. image.setContentID(cid);
    144. // 描述正文和图片的关系
    145. MimeMultipart photo = new MimeMultipart();
    146. photo.addBodyPart(text);
    147. photo.addBodyPart(image);
    148. photo.setSubType("related");
    149. MimeBodyPart mimeBodyPart = new MimeBodyPart();
    150. mimeBodyPart.setContent(photo);
    151. // 将图片放入body中
    152. mimeMultipart.addBodyPart(mimeBodyPart);
    153. }
    154. }
    155. /*// 以下方式所有图片公用一个标题
    156. MimeMultipart photo = new MimeMultipart();
    157. MimeBodyPart text = new MimeBodyPart();
    158. photo.addBodyPart(text);
    159. StringBuilder textContent = new StringBuilder(javaMailInfo.getContent());
    160. if (!CollectionUtils.isEmpty(photoUrlList)) {
    161. for (String photoUrl : photoUrlList) {
    162. // 设置图片标题 注意img标签的引用位置 用cid:开头
    163. String cid = UUID.randomUUID().toString();
    164. textContent.append("<br/><img src=\'cid:"+ cid +".jpg\'>");
    165. // 使用数据处理器处理图片
    166. MimeBodyPart image = new MimeBodyPart();
    167. image.setDataHandler(new DataHandler(new FileDataSource(photoUrl)));
    168. image.setContentID(cid);
    169. // 描述正文和图片的关系
    170. photo.addBodyPart(image);
    171. }
    172. photo.setSubType("related");
    173. }
    174. text.setContent(textContent.toString(), "text/html;charset=utf-8");*/
    175. // 设置消息体
    176. mimeMessage.setContent(mimeMultipart);
    177. // mimeMessage.setContent(photo);
    178. mimeMessage.setSentDate(new Date());
    179. mimeMessage.saveChanges();
    180. return mimeMessage;
    181. }
    182. /**
    183. * 根据邮件Session和邮件信息创建邮件内容(附件类 可多个附件)
    184. * @param mailSession
    185. * @param javaMailInfo
    186. * @return
    187. */
    188. private static Message createAttachMail(Session mailSession, JavaMailInfo javaMailInfo) throws MessagingException {
    189. MimeMessage mimeMessage = new MimeMessage(mailSession);
    190. mimeMessage.setFrom(new InternetAddress(javaMailInfo.getFromAddress()));
    191. mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(javaMailInfo.getToAddress()));
    192. mimeMessage.setSubject(javaMailInfo.getSubject(), "text/plain;charset=utf-8");
    193. List<String> attachList = javaMailInfo.getAttachList();
    194. // 创建消息体
    195. MimeMultipart mimeMultipart = new MimeMultipart();
    196. MimeBodyPart text = new MimeBodyPart();
    197. text.setContent(javaMailInfo.getSubject(), "text/html;charset=utf-8");
    198. mimeMultipart.addBodyPart(text);
    199. if (!CollectionUtils.isEmpty(attachList)) {
    200. for (String attach : attachList) {
    201. // 创建附件
    202. MimeBodyPart mimeBodyPart = new MimeBodyPart();
    203. DataHandler dataHandler = new DataHandler(new FileDataSource(attach));
    204. mimeBodyPart.setDataHandler(dataHandler);
    205. mimeBodyPart.setFileName(dataHandler.getName());
    206. // 加入最外面的容器
    207. mimeMultipart.addBodyPart(mimeBodyPart);
    208. }
    209. // 描述关系
    210. mimeMultipart.setSubType("mixed");
    211. }
    212. mimeMessage.setContent(mimeMultipart);
    213. mimeMessage.setSentDate(new Date());
    214. mimeMessage.saveChanges();
    215. return mimeMessage;
    216. }
    217. /**
    218. * 根据邮件Session和邮件信息创建邮件内容(多图片 多附件)
    219. * @param mailSession
    220. * @param javaMailInfo
    221. * @return
    222. */
    223. private static Message createPhotoAndAttachMail(Session mailSession, JavaMailInfo javaMailInfo) throws MessagingException {
    224. MimeMessage mimeMessage = new MimeMessage(mailSession);
    225. mimeMessage.setFrom(new InternetAddress(javaMailInfo.getFromAddress()));
    226. mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(javaMailInfo.getToAddress()));
    227. List<String> photoUrlList = javaMailInfo.getPhotoUrlList();
    228. // 获取所有的图片 公用一个主题
    229. MimeMultipart photo = new MimeMultipart();
    230. MimeBodyPart text = new MimeBodyPart();
    231. photo.addBodyPart(text);
    232. StringBuilder textContent = new StringBuilder(javaMailInfo.getContent());
    233. if (!CollectionUtils.isEmpty(photoUrlList)) {
    234. for (String photoUrl : photoUrlList) {
    235. // 设置图片标题 注意img标签的引用位置 用cid:开头
    236. String cid = UUID.randomUUID().toString();
    237. textContent.append("<br/><img src=\'cid:"+ cid +".jpg\'>");
    238. // 使用数据处理器处理图片
    239. MimeBodyPart image = new MimeBodyPart();
    240. image.setDataHandler(new DataHandler(new FileDataSource(photoUrl)));
    241. image.setContentID(cid);
    242. // 描述正文和图片的关系
    243. photo.addBodyPart(image);
    244. }
    245. photo.setSubType("related");
    246. }
    247. text.setContent(textContent.toString(), "text/html;charset=utf-8");
    248. // 将图片包裹成一个body 作为 其内容
    249. MimeBodyPart content = new MimeBodyPart();
    250. content.setContent(photo);
    251. // 获取所有的附件
    252. List<String> attachList = javaMailInfo.getAttachList();
    253. MimeMultipart attach = new MimeMultipart();
    254. if (!CollectionUtils.isEmpty(attachList)) {
    255. for (String attachUrl : attachList) {
    256. // 创建附件
    257. MimeBodyPart mimeBodyPart = new MimeBodyPart();
    258. DataHandler dataHandler = new DataHandler(new FileDataSource(attachUrl));
    259. mimeBodyPart.setDataHandler(dataHandler);
    260. mimeBodyPart.setFileName(dataHandler.getName());
    261. // 加入最外面的容器
    262. attach.addBodyPart(mimeBodyPart);
    263. }
    264. }
    265. // 将图片body 和 附件组合
    266. attach.addBodyPart(content);
    267. attach.setSubType("mixed");
    268. mimeMessage.setContent(attach);
    269. mimeMessage.setSentDate(new Date());
    270. mimeMessage.saveChanges();
    271. return mimeMessage;
    272. }
    273. }
  • spring提供的JavaMailSender是对原始的javax.mail进行了简化

  • 再其使用过程中可以注册到spring容器中,也可不用注册

  • 导入依赖

    1. javax.mail的依赖包
    2. <dependency>
    3. <groupId>org.springframework</groupId>
    4. <artifactId>spring-context-support</artifactId>
    5. </dependency>
  1. 邮件的基本信息类

    1. @Data
    2. public class JavaMailSenderInfo {
    3. // 收件人地址
    4. private String toAddress;
    5. // 邮件主题
    6. private String subject;
    7. // 邮件内容
    8. private String content;
    9. // 是否是html 注意字段boolean类型 不要用is开头 idea会生成get,set方法会进行优化 isHtml -> isHtml(),getHtml() -- html -> isHtml(),getHtml()
    10. private boolean html = false;
    11. // 图片地址集合
    12. private List<String> photoList;
    13. // 附件地址集合
    14. private List<String> attachList;
    15. }
  2. 准备mail.propertise配置文件(也就是设置会话的属性),文件放在resource目录下

    1. #传输协议
    2. mail.transport.protocol=smtp
    3. #服务器主机名
    4. mail.smtp.host=smtp.qq.com
    5. #服务器端口号 465或587(使用ssl)
    6. mail.smtp.port=465
    7. #是否进行用户名密码校验 配置了否 就不能配置 用户名和密码 否则会去获取用户名密码进行验证
    8. mail.smtp.auth=true
    9. #设置是否使用ssl安全连接 ---一般都使用
    10. mail.smtp.ssl.enable=true
    11. #设置是否显示debug信息 true 会在控制台显示相关信息
    12. mail.debug=true
    13. #设置超时时间
    14. mail.smtp.timeout=20000
    15. #编码格式
    16. mail.smtp.defaultEncoding=utf-8
    17. #你的邮箱地址
    18. mail.smtp.username=xxxxxx@qq.com
    19. #你的授权码(第三方使用时代替密码)
    20. mail.smtp.password=xxxxxx
  3. 加载配置文件,初始化JavaMailSender

    1. public class InitJavaMailSender {
    2. /**
    3. * 此类的作用是加载配置文件来创建JavaMailSender对象 JavaMailSenderImpl是该接口的实现类
    4. * 因此我们需要对JavaMailSenderImpl进行配置 在spring的环境下 我们可以使用加载配置文件的方式 或者
    5. * 在spring配置文件中直接配置该bean(由spring托管)使用时@Autowired直接注入即可
    6. * <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    7. * <property name="host" value="${mail.smtp.host}" />
    8. * <property name="username" value="${mail.smtp.username}" />
    9. * <property name="password" value="${mail.smtp.password}" />
    10. * <property name="defaultEncoding" value="${mail.smtp.defaultEncoding}" />
    11. * <property name="javaMailProperties">
    12. * <props>
    13. * <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
    14. * <prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop>
    15. * ...
    16. * </props>
    17. * </property>
    18. * </bean>
    19. * 本次采用加载配置文件的方式
    20. * 由spring提供 其底层使用的仍然是javax.mail进行邮件的发送
    21. * JavaMailSenderImpl 依赖javax.mail 和 spring-context-support包
    22. */
    23. // 传输协议
    24. private static String protocol;
    25. // 服务器主机名
    26. private static String host;
    27. // 服务器端口号
    28. private static String port;
    29. // 是否进行用户名密码校验
    30. private static String auth;
    31. // 设置是否使用ssl安全连接
    32. private static String enableSSL;
    33. // 设置是否显示debug信息
    34. private static String debug;
    35. // 超时时间
    36. private static String timeout;
    37. // 编码格式
    38. private static String defaultEncoding;
    39. // 邮箱地址
    40. public static String username;
    41. // 授权码
    42. private static String password;
    43. private static volatile JavaMailSenderImpl javaMailSenderImpl;
    44. static {
    45. init();
    46. }
    47. private static void init() {
    48. // 加载配置文件
    49. Properties properties = new Properties();
    50. InputStream resourceAsStream = JavaMailSender.class.getClassLoader().getResourceAsStream("mail.properties");
    51. try {
    52. properties.load(resourceAsStream);
    53. protocol = properties.getProperty("mail.transport.protocol");
    54. host = properties.getProperty("mail.smtp.host");
    55. port = properties.getProperty("mail.smtp.port");
    56. auth = properties.getProperty("mail.smtp.auth");
    57. enableSSL = properties.getProperty("mail.smtp.ssl.enable");
    58. debug = properties.getProperty("mail.debug");
    59. timeout = properties.getProperty("mail.smtp.timeout");
    60. defaultEncoding = properties.getProperty("mail.smtp.defaultEncoding");
    61. username = properties.getProperty("mail.smtp.username");
    62. password = properties.getProperty("mail.smtp.password");
    63. System.out.println("mail.properties加载成功");
    64. } catch (IOException e) {
    65. e.printStackTrace();
    66. System.out.println("mail.properties加载失败");
    67. } finally {
    68. if (null != resourceAsStream) {
    69. try {
    70. resourceAsStream.close();
    71. } catch (IOException e) {
    72. e.printStackTrace();
    73. }
    74. }
    75. }
    76. }
    77. /**
    78. * 使用单例获取JavaMailSender 双重检查既保证的线程安全 又保证了效率 又能起到延迟加载的作用
    79. * @return
    80. */
    81. public static JavaMailSender getJavaMailSender() {
    82. if (null == javaMailSenderImpl) {
    83. synchronized (InitJavaMailSender.class) {
    84. if (null == javaMailSenderImpl) {
    85. javaMailSenderImpl = new JavaMailSenderImpl();
    86. javaMailSenderImpl.setProtocol(protocol);
    87. javaMailSenderImpl.setHost(host);
    88. javaMailSenderImpl.setPort(Integer.parseInt(port));
    89. javaMailSenderImpl.setDefaultEncoding(defaultEncoding);
    90. javaMailSenderImpl.setUsername(username);
    91. javaMailSenderImpl.setPassword(password);
    92. Properties properties = new Properties();
    93. properties.setProperty("mail.smtp.auth", auth);
    94. properties.setProperty("mail.smtp.ssl.enable", enableSSL);
    95. properties.setProperty("mail.debug", debug);
    96. properties.setProperty("mail.smtp.timeout", timeout);
    97. javaMailSenderImpl.setJavaMailProperties(properties);
    98. }
    99. }
    100. }
    101. return javaMailSenderImpl;
    102. }
    103. }
  4. 邮件发送工具类

    1. public class JavaMailSenderUtils {
    2. /**
    3. * 测试发送邮件 实际中可以在service中使用(若使用的spring配置的方式创建JavaMailSender,则需注入使用)
    4. * 此处为方便使用main方法
    5. * @param args
    6. */
    7. public static void main(String[] args) {
    8. JavaMailSenderInfo javaMailSenderInfo = new JavaMailSenderInfo();
    9. javaMailSenderInfo.setToAddress("发件人");
    10. javaMailSenderInfo.setSubject("邮件主题");
    11. javaMailSenderInfo.setContent("邮件内容");
    12. javaMailSenderInfo.setHtml(true);
    13. List<String> list = new ArrayList<>();
    14. list.add("图片1");
    15. // list.add("图片2");
    16. // list.add("图片3");
    17. // list.add("图片4");
    18. javaMailSenderInfo.setPhotoList(list);
    19. javaMailSenderInfo.setAttachList(list);
    20. // JavaMailSenderUtils.sendSimpleMail(javaMailSenderInfo);
    21. JavaMailSenderUtils.sendPhotoMail(javaMailSenderInfo);
    22. // JavaMailSenderUtils.sendAttacheMail(javaMailSenderInfo);
    23. // JavaMailSenderUtils.sendPhotoAndAttacheMail(javaMailSenderInfo);
    24. }
    25. private static final JavaMailSender javaMailSender = InitJavaMailSender.getJavaMailSender();
    26. private static final String htmlStartStr = "<html><body>";
    27. private static final String htmlEndStr = "</body></html>";
    28. /**
    29. * 发送简单邮件 文本 html
    30. * @param javaMailSenderInfo
    31. * @return
    32. */
    33. public static boolean sendSimpleMail(JavaMailSenderInfo javaMailSenderInfo) {
    34. // 创建邮件消息 简单邮件可直接使用SimpleMailMessage
    35. MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    36. MimeMessageHelper mimeMessageHelper = null;
    37. try {
    38. // 创建消息辅助器 参数二 为true时为多组件 html 等
    39. mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
    40. // 设置公共字段
    41. setMailCommonField(mimeMessageHelper, javaMailSenderInfo);
    42. // 文本内容 可指定是否是html
    43. mimeMessageHelper.setText(javaMailSenderInfo.getContent(), javaMailSenderInfo.isHtml());
    44. javaMailSender.send(mimeMessage);
    45. System.out.println("简单邮件发送成功");
    46. return true;
    47. } catch (MessagingException e) {
    48. e.printStackTrace();
    49. System.out.println("简单邮件发送失败");
    50. return false;
    51. }
    52. }
    53. /**
    54. * 发送带图片的邮件
    55. * @param javaMailSenderInfo
    56. * @return
    57. */
    58. public static boolean sendPhotoMail(JavaMailSenderInfo javaMailSenderInfo) {
    59. // 创建邮件消息 简单邮件可直接使用SimpleMailMessage
    60. MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    61. MimeMessageHelper mimeMessageHelper = null;
    62. try {
    63. mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
    64. setMailCommonField(mimeMessageHelper, javaMailSenderInfo);
    65. List<String> photoList = javaMailSenderInfo.getPhotoList();
    66. // html内容
    67. StringBuilder text = new StringBuilder(htmlStartStr);
    68. text.append(javaMailSenderInfo.getContent());
    69. if (!CollectionUtils.isEmpty(photoList)) {
    70. for (String photo : photoList) {
    71. // 每个图片创建一个标题吧 每个图片关联一个cid
    72. String cid = UUID.randomUUID().toString();
    73. text.append("<br/><h1>"+ javaMailSenderInfo.getSubject() +"</h1><br/><img src=\'cid:"+ cid +"\'/>");
    74. mimeMessageHelper.addInline(cid, new File(photo));
    75. }
    76. }
    77. // 为什么会有最后一个图片图裂不显示的问题(求大佬指点)
    78. // String cid = UUID.randomUUID().toString();
    79. // mimeMessageHelper.addInline(cid, new File(""));
    80. text.append(htmlEndStr);
    81. mimeMessageHelper.setText(text.toString(),true);
    82. javaMailSender.send(mimeMessage);
    83. System.out.println("带图片的邮件发送成功");
    84. return true;
    85. } catch (MessagingException e) {
    86. e.printStackTrace();
    87. System.out.println("带图片的邮件发送失败");
    88. return false;
    89. }
    90. }
    91. /**
    92. * 发送带附件的邮件
    93. * @param javaMailSenderInfo
    94. * @return
    95. */
    96. public static boolean sendAttacheMail(JavaMailSenderInfo javaMailSenderInfo) {
    97. // 创建邮件消息 简单邮件可直接使用SimpleMailMessage
    98. MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    99. MimeMessageHelper mimeMessageHelper = null;
    100. try {
    101. mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
    102. setMailCommonField(mimeMessageHelper, javaMailSenderInfo);
    103. List<String> attachList = javaMailSenderInfo.getAttachList();
    104. // 邮件文本
    105. mimeMessageHelper.setText(javaMailSenderInfo.getContent(), javaMailSenderInfo.isHtml());
    106. if (!CollectionUtils.isEmpty(attachList)) {
    107. for (String attach : attachList) {
    108. // 添加附件(最后一个附件是图片也存在图裂的问题,但可下载使用,求大佬指点)
    109. FileSystemResource fileSystemResource = new FileSystemResource(attach);
    110. // 参数一为附件名称
    111. mimeMessageHelper.addAttachment(fileSystemResource.getFilename(), fileSystemResource);
    112. }
    113. }
    114. javaMailSender.send(mimeMessage);
    115. System.out.println("带附件的邮件发送成功");
    116. return true;
    117. } catch (MessagingException e) {
    118. e.printStackTrace();
    119. System.out.println("带附件的邮件发送失败");
    120. return false;
    121. }
    122. }
    123. /**
    124. * 发送带图片和附件的邮件
    125. * @param javaMailSenderInfo
    126. * @return
    127. */
    128. public static boolean sendPhotoAndAttacheMail(JavaMailSenderInfo javaMailSenderInfo) {
    129. // 创建邮件消息 简单邮件可直接使用SimpleMailMessage
    130. MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    131. MimeMessageHelper mimeMessageHelper = null;
    132. try {
    133. mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
    134. setMailCommonField(mimeMessageHelper, javaMailSenderInfo);
    135. List<String> photoList = javaMailSenderInfo.getPhotoList();
    136. // 放入图片和内容
    137. StringBuilder text = new StringBuilder(htmlStartStr + javaMailSenderInfo.getContent());
    138. if (!CollectionUtils.isEmpty(photoList)) {
    139. for (String photo : photoList) {
    140. String cid = UUID.randomUUID().toString();
    141. text.append("<br/><img src=\'cid:"+ cid +"\'>");
    142. mimeMessageHelper.addInline(cid, new File(photo));
    143. }
    144. }
    145. text.append(htmlEndStr);
    146. mimeMessageHelper.setText(text.toString(),true);
    147. // 放入附件
    148. List<String> attachList = javaMailSenderInfo.getAttachList();
    149. if (!CollectionUtils.isEmpty(attachList)) {
    150. for (String attach : attachList) {
    151. // 添加附件
    152. FileSystemResource fileSystemResource = new FileSystemResource(attach);
    153. // 参数一为附件名称
    154. mimeMessageHelper.addAttachment(fileSystemResource.getFilename(), fileSystemResource);
    155. }
    156. }
    157. javaMailSender.send(mimeMessage);
    158. System.out.println("带图片和附件的邮件发送成功");
    159. return true;
    160. } catch (MessagingException e) {
    161. e.printStackTrace();
    162. System.out.println("带图片和附件邮件发送失败");
    163. return false;
    164. }
    165. }
    166. /**
    167. * 发送由freemarker模板技术生成的邮件
    168. * @param javaMailSenderInfo
    169. * @return
    170. */
    171. public static boolean sendFreemarkerMail(JavaMailSenderInfo javaMailSenderInfo) {
    172. // 创建邮件消息 简单邮件可直接使用SimpleMailMessage
    173. MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    174. MimeMessageHelper mimeMessageHelper = null;
    175. try {
    176. mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
    177. setMailCommonField(mimeMessageHelper, javaMailSenderInfo);
    178. /**
    179. * 此处没有实现采用模板技术(可自行探索)
    180. * 封装模板所需要的数据
    181. * 读取freemarker的模板文件 xxx.ftl 进行静态化,生成html形式的字符串
    182. * 将生成好的html字符串设置到邮件的正文中
    183. */
    184. javaMailSender.send(mimeMessage);
    185. System.out.println("freemarker模板技术生成的邮件发送成功");
    186. return true;
    187. } catch (MessagingException e) {
    188. e.printStackTrace();
    189. System.out.println("freemarker模板技术生成的邮件发送失败");
    190. return false;
    191. }
    192. }
    193. /**
    194. * 设置邮件的公共字段
    195. * @param mimeMessageHelper
    196. * @param javaMailSenderInfo
    197. * @throws MessagingException
    198. */
    199. private static void setMailCommonField(MimeMessageHelper mimeMessageHelper, JavaMailSenderInfo javaMailSenderInfo) throws MessagingException {
    200. // 发件人
    201. mimeMessageHelper.setFrom(InitJavaMailSender.username);
    202. // 收件人 多人用数组
    203. mimeMessageHelper.setTo(javaMailSenderInfo.getToAddress());
    204. // 主题
    205. mimeMessageHelper.setSubject(javaMailSenderInfo.getSubject());
    206. // 日期
    207. mimeMessageHelper.setSentDate(new Date());
    208. }
    209. }
  • 使用springboot发送邮件和使用spring提供的JavaMailSender发送邮件的方式一样

  • 在yml配置文件中配置相关的会话信息后

  • 在service层中直接注入使用即可

  • 导入依赖

    1. <!--springboot整合mail-->
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-mail</artifactId>
    5. </dependency>
  1. 修改配置

    1. # 邮件的设置 导入mail启动包 使用时注入直接JavaMailSender即可
    2. spring:
    3. mail:
    4. protocol: smtp
    5. host: smtp.qq.com
    6. port: 465
    7. default-encoding: utf-8
    8. username: 邮箱用户名
    9. password: 邮箱授权码
    10. test-connection: true
    11. properties:
    12. mail:
    13. debug: true
    14. smtp:
    15. auth: true
    16. timeout: 20000
    17. ssl:
    18. enable: true
  2. 直接在service层中使用即可

    1. public MailServiceImpl {
    2. @Autowired
    3. private JavaMailSender javaMailSender;
    4. // 以下代码使用即可
    5. ...
    6. }

版权声明:本文为xiaokantianse原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xiaokantianse/p/13948245.html