当前位置: 首页 > news >正文

Spring 邮件发送

Spring 邮件发送

1. 主要内容(了解)

2. JavaMail 概述(了解)

  JavaMail,顾名思义,提供给开发者处理电⼦邮件相关的编程接⼝。JavaMail 是由 Sun 定义的⼀套收发电⼦邮件的 API,它可以⽅便地执⾏⼀些常⽤的邮件传输,不同的⼚商可以提供⾃⼰的实现类。但它并没有包含在 JDK 中,⽽是作为 JavaEE 的⼀部分。

  ⼚商所提供的 JavaMail 服务程序可以有选择地实现某些邮件协议,常⻅的邮件协议包括:

SMTP:简单邮件传输协议,⽤于发送电⼦邮件的传输协议;

POP3:⽤于接收电⼦邮件的标准协议;

IMAP:互联⽹消息协议, POP3 的替代协议。

  这三种协议都有对应 SSL 加密传输的协议,分别是 SMTPSPOP3S  IMAPS。除 JavaMail 服务提供程序之外, JavaMail 还需要 JAF(JavaBeans Activation Framework)来处理不是纯⽂本的邮件内容,这包 MIME(多⽤途互联⽹邮件扩展)、URL ⻚⾯和⽂件附件等内容。另外,JavaMail 依赖 JAF(JavaBeans Activation Framework)JAF  Java6 之后已经合并到 JDK 中,⽽ JDK5 之前需要另外下载 JAF 的类库。

2.1. 协议介绍

  在研究 JavaMail API 的细则之前,⾸先需要对于 API ⽤到的协议有个认识。对于 java mail 来说⽤到的协议有常⻅的⼏种: SMTPPOPIMAPMIME

2.1.1. SMTP

  简单邮件传输协议(Simple Mail Transfer ProtocolSMTP)由 RFC 821 定义。它定义了发送电⼦邮件的机制。在 JavaMail API 环境中,您基于 JavaMail 的程序将和您的公司或因特⽹服务供应商的(Internet Service
Provider'sISP'sSMTP 服务器通信。SMTP 服务器会中转消息给接收⽅ SMTP 服务器以便最终让⽤户经由 POP  IMAP 获得。

2.1.2. POP

  POP 代表邮局协议(Post Office Protocol)。⽬前⽤的是版本 3,也称 POP3RFC 1939 定义了这个协议。POP 是⼀种机制,因特⽹上⼤多数⼈⽤它得到邮件。它规定每个⽤户⼀个邮箱的⽀持。这就是它所能做的,⽽这也造成了许多混淆。使⽤ POP3 时,⽤户熟悉的许多性能并不是由 POP 协议⽀持的,如查看有⼏封新邮件消息这⼀性能。这些性能内建于如 Eudora  Microsoft Outlook 之类的程序中,它们能记住⼀些事,诸如最近⼀次收到的邮件,还能计算出有多少是新的。所以当使⽤ JavaMail API 时,如果您想要这类信息,您就必须⾃⼰算。

2.1.3. IMAP

  IMAP 是更⾼级的⽤于接收消息的协议。在 RFC 2060 中被定义,IMAP 代表因特⽹消息访问协议(Internet Message Access Protocol),⽬前⽤的是版本 4,也称 IMAP4。在⽤到 IMAP 时,邮件服务器必需⽀持这个协议。不能仅仅把使⽤ POP 的程序⽤于 IMAP,并指望它⽀持 IMAP 所有性能。假设邮件服务器⽀持 IMAP,基于 JavaMail 的程序可以利⽤这种情况  ⽤户在服务器上有多个⽂件夹(folder),并且这些⽂件夹可以被多个⽤户共享。因为有这⼀更⾼级的性能,您也许会认为所有⽤户都会使⽤ IMAP。事实并不是这样。要求服务器接收新消息,在⽤户请求时发送到⽤户⼿中,还要在每个⽤户的多个⽂件夹中维护消息。这样虽然能将消息集中备份,但随着⽤户⻓期的邮件夹越来越⼤,到磁盘空间耗尽时,每个⽤户都会受到损失。使⽤ POP,就能卸载邮件服务器上保存的消息了。

2.1.4. MIME

  MIME 代表多⽤途因特⽹邮件扩展标准(Multipurpose Internet Mail Extensions)。它不是邮件传输协议。但对传输内容的消息、附件及其它的内容定义了格式。这⾥有很多不同的有效⽂档:RFC 822RFC 2045RFC
2046  RFC 2047。作为⼀个 JavaMail API 的⽤户,您通常不必对这些格式操⼼。⽆论如何,⼀定存在这些格式⽽且程序会⽤到它。

2.2. JavaMail 的关键对象

  JavaMail 对收发邮件进⾏了⾼级的抽象,形成了⼀些关键的的接⼝和类,它们构成了程序的基础,下⾯我们分别来了解⼀下这些最常⻅的对象。

2.2.1. Properties 属性对象

  由于 JavaMail 需要和邮件服务器进⾏通信,这就要求程序提供许多诸如服务器地址、端⼝、⽤户名、密码等信息,JavaMail 通过 Properties 对象封装这些属性信息。如下⾯的代码封装了两个属性信息:

Properties props = new Properties();

props.put("mail.smtp.host", "smtp.sina.com.cn");

props.put("mail.smtp.auth", "true");

  针对不同的的邮件协议,JavaMail 规定了服务提供者必须⽀持⼀系列属性,下表是针对 SMTP 协议的⼀些常⻅属性(属性值都以 String 类型进⾏设置,属性类型栏仅表示属性是如何被解析的):

属性名

类型

说明

mail.smtp.host

String

SMTP 服务器地址,如smtp.sina.com.cn

mail.smtp.port

int

SMTP 服务器端⼝号,默认为 25

mail.smtp.auth

boolean

SMTP 服务器是否需要⽤户认证,默认为 false

mail.smtp.user

String

SMTP 默认的登陆⽤户名

mail.smtp.from

String

默认的邮件发送源地址

mail.smtp.socketFactory.class

String

socket ⼯⼚类类名
通过设置该属性可以覆盖提供者默认的实现,必须实现javax.NET.SocketFactory接⼝

mail.smtp.socketFactory.port

int

指定 socket ⼯⼚类所⽤的端⼝号

如果没有规定,则使⽤默认的端⼝号

mail.smtp.socketFactory.fallback

boolean

设置为 true 时,当使⽤指定的socket 类创建 socket 失败后,将使⽤

Java.net.Socket 创建socket,默认为 true

mail.smtp.timeout

int

I/O 连接超时时间,单位为毫秒,默认为永不超时

 其他⼏个协议也有类似的⼀系列属性,如 POP3  mail.pop3.hostmail.pop3.port 以及IMAP  mail.imap.hostmail.imap.host 等。

2.2.2. Session 会话对象

  Session 是⼀个很容易被误解的类,这归咎于混淆视听的类名。千万不要以为这⾥的 Session  HttpSession ⼀样代表真实的交互会话,但创建 Session 对象时,并没有对应的物理连接,它只不过是⼀对配置信息的集合。

  Session 的主要作⽤,包括两个⽅⾯:

1.  接收各种配置属性信息:通过 Properties 对象设置的属性信息;
2.  初始化 JavaMail 环境:根据 JavaMail 的配置⽂件,初始化 JavaMail 环境,以便通过 Session 对象 创建其他重要类的实例。

2.2.3. Transport  Store 传输和存储

  邮件操作只有发送或接收两种处理⽅式,JavaMail 将这两种不同操作描述为传输
javax.mail.Transport)和存储(javax.mail.Store),传输对应邮件的发送,⽽存储对应邮件的接收。

2.2.4. Message 消息对象

  ⼀旦获得 Session 对象,就可以继续创建要发送的消息。这由 Message 类来完成。因为 Message 是个抽象类,您必需⽤⼀个⼦类,多数情况下为 javax.mail.internet.MimeMessageMimeMessage 是个能理 MIME 类型和头的电⼦邮件消息,正如不同 RFC 中所定义的。虽然在某些头部域⾮ ASCII 字符也能被译码,但 Message 头只能被限制为⽤ US-ASCII 字符。

2.2.5. Address 地址

  ⼀旦您创建了 Session  Message,并将内容填⼊消息后,就可以⽤ Address 确定信件地址了。 Message ⼀样,Address 也是个抽象类。您⽤的是 javax.mail.internet.InternetAddress 类。若创建的地址只包含电⼦邮件地址,只要传递电⼦邮件地址到构造器就⾏了。

2.2.6. Authenticator 认证者

   java 类⼀样,JavaMail API 也可以利⽤ Authenticator 通过⽤户名和密码访问受保护的资源。对 JavaMail API 来说,这些资源就是邮件服务器。JavaMail Authenticator  javax.mail 包中,⽽且它 java.net 中同名的类 Authenticator 不同。两者并不共享同⼀个 Authenticator,因为 JavaMail API  Java 1.1,它没有 java.net 类别。要使⽤ Authenticator,先创建⼀个抽象类的⼦类,并 
getPasswordAuthentication() ⽅法中返回 PasswordAuthentication 实例。创建完成后,您必需向 session 注册 Authenticator。然后,在需要认证的时候,就会通知 Authenticator。您可以弹出窗⼝,也可以从配置⽂件中(虽然没有加密是不安全的)读取⽤户名和密码,将它们作为 PasswordAuthentication 对象返回给调⽤程序。

3. Java Mail 环境准备(操作)

3.1. 设置邮箱服务

这⾥是以163邮箱为例

注册 163 邮箱,登录 163 邮箱后,设置邮箱账户开通 smtp 服务

  需要根据注册时的⼿机号发送的验证码来开通获取邮箱客户端授权码。开通成功后,会显示个⼈授权访问码,该授权码是后⾯通过 Java mail 发送邮件的认证密码,⾮常重要。

3.2. 添加依赖

创建 Maven 项⽬,在 pom.xml 配置⽂件中添加 mail 的所需的依赖

<!-- Java Mail -->

<dependency>

 <groupId>com.sun.mail</groupId>

 <artifactId>javax.mail</artifactId>

 <version>1.6.2</version>

</dependency>

<dependency>

 <groupId>javax.mail</groupId>

 <artifactId>javax.mail-api</artifactId>

 <version>1.6.2</version>

</dependency>

4. Java Mail 发送邮件(操作)

4.1. 发送普通⽂本的邮件

package com.xxxx.mail;
import javax.activation.DataHandler;import javax.activation.FileDataSource;import javax.mail.*;import javax.mail.internet.*;import java.io.UnsupportedEncodingException;import java.util.Date;import java.util.Properties;/*** 发送普通⽂本的邮件*/public class MailTest01 {public static void main(String[] args) throws Exception {// 定义邮箱服务器配置Properties prop = new Properties();// 设置邮件服务器主机名 (163 邮件服务器地址:"mail.smtp.host"  "smtp.163.com") prop.setProperty("mail.smtp.host", "smtp.163.com");// 设置邮件服务器的端⼝prop.setProperty("mail.smtp.port", "25");// 设置邮件服务器认证属性 (设置为true表示发送服务器需要身份验证) prop.setProperty("mail.smtp.auth", "true");// 某些邮箱服务器要求 SMTP 连接需要使⽤ SSL 安全认证// prop.setProperty("mail.smtp.port", "465");// prop.setProperty("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");// prop.setProperty("mail.smtp.socketFactory.fallback", "false"); // prop.setProperty("mail.smtp.socketFactory.port", "465");// 使⽤JavaMail发送邮件的5个步骤// 1. 创建sessionSession session = Session.getInstance(prop);// 开启Session的debug模式,这样就可以查看到程序发送Email的运⾏状态 session.setDebug(true);// 2. 通过session得到transport对象Transport ts = session.getTransport();// 3. 使⽤邮箱的⽤户名和密码连上邮件服务器(⽤户名只需写@前⾯的即可,密码是指授权码) ts.connect("smtp.163.com", "⽤户名", "密码");// 4. 创建邮件// 发送普通⽂本的邮件Message message = createSimpleTxtMail(session);// 5. 发送邮件ts.sendMessage(message, message.getAllRecipients()); // 关闭transport对象ts.close();}/*** 普通⽂本邮件*      创建⼀封只包含⽂本的邮件* @param session* @return*/public static MimeMessage createSimpleTxtMail(Session session) throws MessagingException {// 创建邮件对象MimeMessage message = new MimeMessage(session);// 设置邮件的发件⼈的邮箱地址message.setFrom(new InternetAddress("发件⼈的邮箱地址"));// 设置邮件的收件⼈的邮箱地址 (现在发件⼈和收件⼈是⼀样的,那就是⾃⼰给⾃⼰发)message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件⼈的邮箱地址"));// 发送给多个收件⼈// message.setRecipients(Message.RecipientType.TO, new InternetAddress[] {}); // Cc: 抄送(可选)// message.setRecipient(MimeMessage.RecipientType.CC, newInternetAddress(""));// Bcc: 密送(可选)// message.setRecipient(MimeMessage.RecipientType.BCC, newInternetAddress(""));// 邮件的主题message.setSubject("测试⽂本邮件");// 设置发送⽇期message.setSentDate(new Date());// 邮件的⽂本内容 (setText():纯⽂本内容)message.setText("你好,这是⼀封测试邮件!");// 返回创建好的邮件对象return message;}}

效果如下:

4.2. 发送HTML内容的邮件

package com.xxxx.mail;import javax.activation.DataHandler;import javax.activation.FileDataSource;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;import java.util.Date;import java.util.Properties;/*** 发送HTML内容的邮件*/public class MailTest02 {public static void main(String[] args) throws Exception {// 定义邮箱服务器配置Properties prop = new Properties();// 设置邮件服务器主机名 (163 邮件服务器地址:"mail.smtp.host"  "smtp.163.com") prop.setProperty("mail.smtp.host", "smtp.163.com");// 设置邮件服务器的端⼝prop.setProperty("mail.smtp.port", "25");// 设置邮件服务器认证属性 (设置为true表示发送服务器需要身份验证) prop.setProperty("mail.smtp.auth", "true");// 使⽤JavaMail发送邮件的5个步骤// 1. 创建sessionSession session = Session.getInstance(prop);// 开启Session的debug模式,这样就可以查看到程序发送Email的运⾏状态 session.setDebug(true);// 2. 通过session得到transport对象Transport ts = session.getTransport();// 3. 使⽤邮箱的⽤户名和密码连上邮件服务器(⽤户名只需写@前⾯的即可,密码是指授权码) ts.connect("smtp.163.com", "⽤户名", "密码");// 4. 创建邮件// 发送HTML内容的邮件Message message = createHtmlMail(session);// 5. 发送邮件ts.sendMessage(message, message.getAllRecipients()); // 关闭transport对象ts.close();}/*** HTML内容邮件*      创建⼀封包含html内容的邮件*/public static MimeMessage createHtmlMail(Session session) throws Exception {// 创建邮件对象MimeMessage message = new MimeMessage(session);// 设置邮件的发件⼈的邮箱地址message.setFrom(new InternetAddress("发件⼈的邮箱地址"));// 设置邮件的收件⼈的邮箱地址 (现在发件⼈和收件⼈是⼀样的,那就是⾃⼰给⾃⼰发)message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件⼈的邮箱地址"));// 邮件的主题message.setSubject("测试HTML邮件");// 设置发送⽇期message.setSentDate(new Date());// 准备邮件数据/*** Message表示⼀个邮件,messgaes.getContent()返回⼀个Multipart对象。* ⼀个Multipart对象包含⼀个或多个BodyPart对象,来组成邮件的正⽂部分(包括附件)。*/// 创建多媒体对象MimeMultipart multipart = new MimeMultipart();// 创建邮件体对象MimeBodyPart bodyPart = new MimeBodyPart();// 设置HTML内容StringBuffer sb = new StringBuffer();sb.append("<html><body><a href='http://www.baidu.com'>百度⼀下</a></body></html>");bodyPart.setContent(sb.toString(), "text/html;charset=UTF-8");// 将bodyPart对象设置到multipart对象中multipart.addBodyPart(bodyPart);// 将multipart对象设置到message对象中 (setContent():) message.setContent(multipart);// 返回创建好的邮件对象return message;}   }

效果如下:

4.3. 发送包含附件的邮件

package com.xxxx.mail;import javax.activation.DataHandler;import javax.activation.FileDataSource;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;import java.util.Date;import java.util.Properties;/*** 发送包含附件的邮件*/public class MailTest03 {public static void main(String[] args) throws Exception {// 定义邮箱服务器配置Properties prop = new Properties();// 设置邮件服务器主机名 (163 邮件服务器地址:"mail.smtp.host"  "smtp.163.com") prop.setProperty("mail.smtp.host", "smtp.163.com");// 设置邮件服务器的端⼝prop.setProperty("mail.smtp.port", "25");// 设置邮件服务器认证属性 (设置为true表示发送服务器需要身份验证) prop.setProperty("mail.smtp.auth", "true");// 使⽤JavaMail发送邮件的5个步骤// 1. 创建sessionSession session = Session.getInstance(prop);// 开启Session的debug模式,这样就可以查看到程序发送Email的运⾏状态 session.setDebug(true);// 2. 通过session得到transport对象Transport ts = session.getTransport();// 3. 使⽤邮箱的⽤户名和密码连上邮件服务器(⽤户名只需写@前⾯的即可,密码是指授权码) ts.connect("smtp.163.com", "⽤户名", "密码");// 4. 创建邮件// 发送包含附件的邮件Message message = createAttachMail(session);// 5. 发送邮件ts.sendMessage(message, message.getAllRecipients()); // 关闭transport对象ts.close();}/*** 包含附件的邮件*      创建⼀封包含附件的邮件* @param session* @return* @throws MessagingException*/public static MimeMessage createAttachMail(Session session) throws MessagingException {// 创建邮件对象MimeMessage message = new MimeMessage(session);// 设置邮件的发件⼈的邮箱地址message.setFrom(new InternetAddress("发件⼈的邮箱地址"));// 设置邮件的收件⼈的邮箱地址 (现在发件⼈和收件⼈是⼀样的,那就是⾃⼰给⾃⼰发)message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件⼈的邮箱地址"));// 邮件的主题message.setSubject("测试包含附件的邮件");// 设置发送⽇期message.setSentDate(new Date());// 创建邮件正⽂MimeBodyPart bodyPart = new MimeBodyPart();bodyPart.setContent("使⽤JavaMail创建的带附件的邮件", "text/html;charset=UTF-8");// 创建附件MimeBodyPart attachPart = new MimeBodyPart();// 本地⽂件DataHandler dh = new DataHandler(new FileDataSource("C:\\work\\邮件附件.txt")); attachPart.setDataHandler(dh);// 附件名attachPart.setFileName(dh.getName());// 创建容器描述数据关系MimeMultipart multipart = new MimeMultipart();// 添加正⽂multipart.addBodyPart(bodyPart);// 添加附件multipart.addBodyPart(attachPart);// 如果在邮件中要添加附件,设置为mixed;。multipart.setSubType("mixed");// 设置邮件的内容message.setContent(multipart);// 返回创建好的邮件对象return message;}}

效果如下:

4.4. Java Mail 邮件发送封装

4.4.1. 创建邮件发送信息类

package com.xxxx.mail;import java.util.List;/*** 邮件发送信息类*   定义发送邮件时 邮件服务器 端⼝ 发送⽅⽤户名 密码等字段*/public class MailSendInfo {private String serverHost; // 服务器主机private String serverPort; // 服务器端⼝private String fromAddress;// 发送⽅邮箱地址private List<String> toAddress; // 接收⽅邮箱地址private String userName; // 邮件服务器⽤户名private String userPwd; // 邮件服务器密码(授权密码)private String subject; // 邮件主题private String content; // 邮件内容private Boolean flag = true; // 是否需要身份认证private List<String> attachFileNames; // 附件⽂件名public Boolean getFlag() {return flag;}public void setFlag(Boolean flag) {this.flag = flag;}public String getServerHost() {return serverHost;}public void setServerHost(String serverHost) {this.serverHost = serverHost;}public String getServerPort() {return serverPort;}public void setServerPort(String serverPort) {this.serverPort = serverPort;}public String getFromAddress() {return fromAddress;}public void setFromAddress(String fromAddress) {this.fromAddress = fromAddress;}public List<String> getToAddress() {return toAddress;}public void setToAddress(List<String> toAddress) {this.toAddress = toAddress;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserPwd() {return userPwd;}public void setUserPwd(String userPwd) {this.userPwd = userPwd;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public List<String> getAttachFileNames() {return attachFileNames;}public void setAttachFileNames(List<String> attachFileNames) {  this.attachFileNames = attachFileNames;}}

4.4.2. 创建认证类

package com.xxxx.mail;import javax.mail.Authenticator;import javax.mail.PasswordAuthentication;/*** 认证类*/public class MyAuthenticator extends Authenticator {private String userName; // 邮箱private String userPwd; // 密码(授权码)public MyAuthenticator(String userName, String userPwd) {  this.userName = userName;this.userPwd = userPwd;}/*** 邮件服务器发送邮件时,进⾏身份验证* @return*/@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(userName, userPwd);}}

4.4.3. 创建邮件发送器

package com.xxxx.mail;import javax.activation.DataHandler;import javax.activation.FileDataSource;import javax.mail.*;import javax.mail.internet.*;import java.io.File;import java.util.Date;import java.util.List;import java.util.Properties;public class MailSender {public void sendMail(MailSendInfo mailSendInfo){Message message = null;Session session = null;try {// 定义邮箱服务器配置Properties props = new Properties();// 163 邮件服务器地址props.put("mail.smtp.host", mailSendInfo.getServerHost());// 163 邮件服务器端⼝props.put("mail.smtp.port",mailSendInfo.getServerPort());// 163 邮件服务器认证属性props.put("mail.smtp.auth", mailSendInfo.getFlag());// 身份认证类MyAuthenticator authenticator = new MyAuthenticator(mailSendInfo.getUserName(), mailSendInfo.getUserPwd());// 创建sessionsession = Session.getDefaultInstance(props, authenticator);// 开启Session的debug模式,这样就可以查看到程序发送Email的运⾏状态session.setDebug(true);// 创建message邮件对象message = new MimeMessage(session);// 设置发送⽅的邮箱地址Address from = new InternetAddress(mailSendInfo.getFromAddress());message.setFrom(from);// 设置发送时间message.setSentDate(new Date());// 判断接收⽅的邮箱地址if(null != mailSendInfo.getToAddress() && mailSendInfo.getToAddress().size() > 0){// 定义数组Address[] addresses = new Address[mailSendInfo.getToAddress().size()];// 循环获取接收⽅的邮箱地址,并设置到对应的address数组中for(int i = 0; i < mailSendInfo.getToAddress().size(); i++){  Address address = new InternetAddress(mailSendInfo.getToAddress().get(i));addresses[i] = address;}// 设置接收⽅的邮箱地址message.setRecipients(Message.RecipientType.TO, addresses); // 设置邮件主题message.setSubject(mailSendInfo.getSubject());// 创建多媒体对象容器Multipart multipart = new MimeMultipart();// 创建正⽂内容BodyPart bodyPart =new MimeBodyPart();bodyPart.setContent(mailSendInfo.getContent(),"text/html;charset=utf-8");// 添加正⽂ (将正⽂内容设置到多媒体对象容器中)multipart.addBodyPart(bodyPart);// 获取所有的附件内容List<String> files = mailSendInfo.getAttachFileNames(); // 判断是否包含附件内容if(null != files && files.size() > 0){for(int i = 0; i < files.size(); i++){// 获取对应的附件对象File tempFile = new File(files.get(i));// 判断附件是否存在if(tempFile.exists()){// 如果附件存在,创建附件对象BodyPart attachPart = new MimeBodyPart();attachPart.setDataHandler(new DataHandler(new FileDataSource(tempFile)));// 设置⽂件名 (解决附件名乱码)attachPart.setFileName(MimeUtility.encodeText(tempFile.getName()));// 添加附件 (将附件内容添加到多媒体对象容器中)multipart.addBodyPart(attachPart);}}}// 设置邮件内容message.setContent(multipart);// 发送邮件Transport.send(message);}} catch (Exception e) {e.printStackTrace();}}}

4.4.4. 邮件发送测试
4.4.4.1. 发送HTML内容的邮件
/*** 发送HTML内容的邮件*/public static void testHtmlMail() {MailSendInfo mailSendInfo = new MailSendInfo();mailSendInfo.setServerHost("smtp.163.com");mailSendInfo.setServerPort("25");mailSendInfo.setUserName("邮箱⽤户名");mailSendInfo.setUserPwd("密码(授权码)");mailSendInfo.setSubject("邮件封装");mailSendInfo.setFromAddress("发件⼈的邮箱地址");mailSendInfo.setContent("<h2>这是封装后发送的邮件</h2>");List<String> users = new ArrayList<>();users.add("收件⼈的邮箱地址");mailSendInfo.setToAddress(users);MailSender mailSender=new MailSender();mailSender.sendMail(mailSendInfo);}

效果如下:

4.4.4.2. 发送包含附件的邮件

/*** 发送包含附件的邮件*/public static void testAttachMail() {MailSendInfo mailSendInfo = new MailSendInfo();mailSendInfo.setServerHost("smtp.163.com");mailSendInfo.setServerPort("25");mailSendInfo.setUserName("⽤户名");mailSendInfo.setUserPwd("密码(授权码)");mailSendInfo.setSubject("邮件封装");mailSendInfo.setFromAddress("发件⼈的邮箱地址");mailSendInfo.setContent("<h2>包含附件的邮件</h2>");List<String> users = new ArrayList<>();users.add("收件⼈的邮箱地址");mailSendInfo.setToAddress(users);// 添加附件List<String> files=new ArrayList<String>();files.add("C:\\work\\邮件附件.txt");files.add("C:\\work\\名单.xlsx");mailSendInfo.setAttachFileNames(files);MailSender mailSender=new MailSender();mailSender.sendMail(mailSendInfo);}

效果如下:

5. 使⽤ Spring API 实现邮件发送(操作)

5.1. 环境准备

创建 Maven 项⽬,在 pom.xml ⽂件中添加依赖

<!-- spring核⼼ jar 依赖 -->

<dependency>

 <groupId>org.springframework</groupId>

 <artifactId>spring-context</artifactId>

 <version>5.2.4.RELEASE</version>

</dependency>

<!--spring 上下⽂环境 ⽀持-->

<dependency>

 <groupId>org.springframework</groupId>

 <artifactId>spring-context-support</artifactId>

 <version>5.2.4.RELEASE</version>

</dependency>

<dependency>

 <groupId>org.springframework</groupId>

 <artifactId>spring-test</artifactId>

 <version>5.2.4.RELEASE</version>

 <scope>test</scope>

</dependency>

<!-- Java Mail坐标依赖 -->

<dependency>

 <groupId>com.sun.mail</groupId>

 <artifactId>javax.mail</artifactId>

 <version>1.6.2</version>

</dependency>

5.2. 配置邮件发送 bean

 spring.xml 配置⽂件中设置邮件发送对应的bean标签

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"  xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd">

 <!-- 开启⾃动化扫描  -->

 <context:component-scan base-package="com.xxxx"/>

 <!-- 邮件发送器(提供了邮件发送接⼝、透明创建Java MailMimeMessage、及邮件发送的配置) -->  <bean id="mailSender" 
class="org.springframework.mail.javamail.JavaMailSenderImpl">

 <property name="host" value="smtp.163.com" />

 <property name="port" value="25" />
 <property name="defaultEncoding" value="utf-8"></property> <property name="username" value="⽤户名"></property>

 <property name="password" value="密码"></property>

 </bean>

 <!-- 普通⽂本邮件对象 -->
 <bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">  <property name="from" value="发件⼈的邮箱地址" />

 <property name="subject" value="spring_mail" />

 </bean>

</beans>

5.3. 定义接⼝与实现类

定义接⼝

package com.xxxx.springMail;/*** 定义接⼝*/public interface OrderManager {void placeOrder();}

定义实现类

package com.xxxx.springMail;import org.springframework.mail.MailException;import org.springframework.mail.SimpleMailMessage;import org.springframework.mail.javamail.JavaMailSenderImpl;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Servicepublic class SimpleOrderManager implements OrderManager {@Resourceprivate JavaMailSenderImpl mailSender;@Resourceprivate SimpleMailMessage templateMessage;@Overridepublic void placeOrder() {// 获取邮件对象SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage); // 设置邮件收件⼈的邮箱地址msg.setTo("收件⼈的邮箱地址");// 设置邮件内容msg.setText("Hello Spring Mail");try{// 发送邮件this.mailSender.send(msg);} catch (MailException ex) {System.err.println(ex.getMessage());}}}

5.4. 邮件发送测试

/***  发送邮件* @param args*/public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");  SimpleOrderManager simpleOrderManager = (SimpleOrderManager) ac.getBean("simpleOrderManager");simpleOrderManager.placeOrder();}

5.5. 发送附件

/***  发送包含附件的邮件* @param args* @throws MessagingException*/
public static void main(String[] args) throws MessagingException {ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");  JavaMailSender mailSender= (JavaMailSender) ac.getBean("mailSender");  MimeMessage message= mailSender.createMimeMessage();message.setSubject("spring_mail"); // 邮件主题// 创建带有附件的消息帮组类MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8"); helper.setTo(new InternetAddress("收件⼈的邮箱地址"));//设置接收⼈helper.setText("Thank you for ordering!"); // 邮件内容helper.setFrom("发件⼈的邮箱地址"); // 发件⼈// 设置附件File file = new File("C:\\work\\邮件附件.txt");// 添加附件helper.addAttachment(file.getName(), file);// 发送邮件mailSender.send(message);}

相关文章:

Spring 邮件发送

Spring 邮件发送 1. 主要内容&#xff08;了解&#xff09; 2. JavaMail 概述&#xff08;了解&#xff09; JavaMail&#xff0c;顾名思义&#xff0c;提供给开发者处理电⼦邮件相关的编程接⼝。JavaMail 是由 Sun 定义的⼀套收发电⼦邮件的 API&#xff0c;它可以⽅便地执⾏⼀…...

利用 360 安全卫士极速版关闭电脑开机自启动软件教程

在使用电脑的过程中&#xff0c;过多的开机自启动软件会严重拖慢电脑的开机速度&#xff0c;影响我们的使用体验。本教程中简鹿办公将详细介绍如何使用 360 安全卫士极速版关闭电脑开机自启动软件&#xff0c;让您的电脑开机更加迅速流畅。 一、打开 360 安全卫士极速版 在电…...

楼房销售系统

文末获取源码和万字论文&#xff0c;制作不易&#xff0c;感谢点赞支持。 毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;楼房销售系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xf…...

UML箭线图的理解和实践

在软件开发的世界里&#xff0c;UML&#xff08;统一建模语言&#xff09;作为一种标准化的建模语言&#xff0c;扮演着举足轻重的角色。UML类图更是软件开发设计和架构过程中的核心工具&#xff0c;它不仅能帮助开发者明确系统中的类及其关系&#xff0c;还能为后续的代码实现…...

Qt入门8——Qt文件

1. Qt文件概述 文件操作是应用程序必不可少的部分。Qt作为⼀个通用开发库&#xff0c;提供了跨平台的文件操作能力。Qt 提供了很多关于文件的类&#xff0c;通过这些类能够对文件系统进行操作&#xff0c;如文件读写、文件信息获取、文件复制或重命名等。 2. 输入输出设备类 在…...

鸿翼受邀出席2024海峡两岸档案暨缩微学术交流会

近日&#xff0c;由中国档案学会、中国文献影像技术协会共同主办&#xff0c;中华档案暨资讯微缩管理学会参加的2024年海峡两岸档案暨缩微学术交流会在乌鲁木齐召开。鸿翼联合创始人兼CTO罗永秀受邀出席本次交流会并作主题分享。 自1992年以来&#xff0c;该学术交流会已连续举…...

支持win7系统的onnxruntime

在win7 X86系统上&#xff0c;使用了onnxruntime.dll库做AI识别&#xff0c;但是在win7上运行报0xc0000005的错误 经查&#xff0c;ONNX Runtime从v1.15.0版本开始不再支持Windows 7及其之前的操作系统&#xff0c;即便尝试重新编译源代码亦无法在这些老系统上运行&#xff0c;…...

如何利用内链策略提升网站的整体权重?

内链是谷歌SEO中常常被低估的部分&#xff0c;实际上&#xff0c;合理的内链策略不仅能帮助提升页面间的关联性&#xff0c;还可以增强网站的整体权重。通过正确的内链布局&#xff0c;用户可以更流畅地浏览你的网站&#xff0c;谷歌爬虫也能更快地抓取到更多页面&#xff0c;有…...

鸿蒙分享(二):引入zrouter路由跳转+封装

码仓库&#xff1a;https://gitee.com/linguanzhong/share_harmonyos 鸿蒙api:12 鸿蒙第三方库地址&#xff1a;OpenHarmony三方库中心仓 zrouter地址&#xff1a;OpenHarmony三方库中心仓 1.引入zrouter 1.打开终端界面&#xff1a;输入 ohpm install hzw/zrouter 2.在项目…...

【计算机网络】实验11:边界网关协议BGP

实验11 边界网关协议BGP 一、实验目的 本次实验旨在验证边界网关协议&#xff08;BGP&#xff09;的实际作用&#xff0c;并深入学习在路由器上配置和使用BGP协议的方法。通过实验&#xff0c;我将探索BGP在不同自治系统之间的路由选择和信息交换的功能&#xff0c;理解其在互…...

leetcode 1853 转换日期格式(postgresql)

需求 表: Days ----------------- | Column Name | Type | ----------------- | day | date | ----------------- day 是这个表的主键。 给定一个Days表&#xff0c;请你编写SQL查询语句&#xff0c;将Days表中的每一个日期转化为"day_name, month_name day, year"…...

掌握时间,从`datetime`开始

文章目录 掌握时间&#xff0c;从datetime开始第一部分&#xff1a;背景介绍第二部分&#xff1a;datetime库是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 获取当前日期和时间2. 创建特定的日期3. 计算两个日期…...

剖析千益畅行,共享旅游-卡,合规运营与技术赋能双驱下的旅游新篇

在数字化浪潮席卷各行各业的当下&#xff0c;旅游产业与共享经济模式深度融合&#xff0c;催生出旅游卡这类新兴产品。然而&#xff0c;市场乱象丛生&#xff0c;诸多打着 “共享” 幌子的旅游卡弊病百出&#xff0c;让从业者与消费者都深陷困扰。今天&#xff0c;咱们聚焦技术…...

集合框架(2)List

Collection的子接口&#xff1a;List、Set 1、List接口 鉴于Java中数组用来存储数据的局限性&#xff0c;我们通常使用java.util.List替代数组List集合类中元素有序、且可重复&#xff0c;集合中的每个元素都有其对应的顺序索引。JDK API中List接口的实现类常用的有&#xff…...

【子查询】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...

西安理工大学丨ChatGPT助力学术论文写作训练营-助力发表SCI一区、二区

在当今学术研究中&#xff0c;科研人员在撰写论文时面临诸多挑战。首先是信息量的剧增&#xff0c;科研人员需要快速消化新知识&#xff0c;筛选相关信息并清晰表达。但论文写作不仅是信息的罗列&#xff0c;还需要条理清晰、逻辑严密、语言精准&#xff0c;特别是在竞争激烈的…...

go get依赖包失败,502 Bad gateway

问题描述 go get 依赖包失败&#xff0c;502 Bad gateway 解决办法 # 临时 export GOPROXY"https://goproxy.cn" go get -u xxxx # 或者直接永久生效 go env -w GOPROXY"https://goproxy.cn"...

71、docker镜像制作上传/下载到阿里云

基本思想:简单学习一下如何制作镜像和上传下载到私有阿里云,然后构建一个gpu的训练/推理环境,以备后续使用 一、配置环境 ubuntu@ubuntu:~$ sudo apt-get install docker.ioubuntu@ubuntu:~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS P…...

ZLMediaKit+wvp (ffmpeg+obs)推拉流测试

这里使用了两种方式: ffmpeg命令和 OBS OBS推流在网上找了些基本没有说明白的, 在ZLMediaKit的issues中看到了一个好大哥的提问在此记录一下 使用OBS推流&#xff0c;rtmp&#xff0c;报鉴权失败 推流 1. ffmpeg命令推流 官方说明文档地址: 推流规则 rtsp://192.168.1.4:10554…...

POSTGRESQL跟ORACLE语法区别和相同之处

跟ORACLE语法区别之处 1. Update和delete语法区别 Pg 和MySQL Update和delete的时候表名不能加别名 2. 插入数字类型不一样 ORACLE 对number类型的数据可以用’’ 字符串标记插入&#xff0c;但是PG不行&#xff0c;必须要进行正确的数据类型 3. SEQ使用不同 ORACEL的SEQ…...

【知识点】图与图论入门

何为图论 见名知意&#xff0c;图论 (Graph Theory) 就是研究 图 (Graph) 的数学理论和方法。图是一种抽象的数据结构&#xff0c;由 节点 (Node) 和 连接这些节点的 边 (Edge) 组成。图论在计算机科学、网络分析、物流、社会网络分析等领域有广泛的应用。 如下&#xff0c;这…...

FPGA系列,文章目录

前言 FPGA&#xff08;Field-Programmable Gate Array&#xff0c;现场可编程门阵列&#xff09;是一种集成电路&#xff0c;其内部结构可以通过软件重新配置来实现不同的逻辑功能。与传统的ASIC&#xff08;Application-Specific Integrated Circuit&#xff0c;专用集成电路…...

PAT乙级1003我要通过的做题笔记

分析题意 得到“答案正确”的条件是&#xff1a; 字符串中必须仅有 P、 A、 T这三种字符&#xff0c;不可以包含其它字符&#xff1b; 任意形如 xPATx 的字符串都可以获得“答案正确”&#xff0c;其中 x 或者是空字符串&#xff0c;或者是仅由字母 A 组成的字符串&#xff1…...

【React】React常用开发工具

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、React DevTools二、Redux DevTools三、Create React App 前言 React 是一种用于构建用户界面的流行 JavaScript 库&#xff0c;由于其灵活性、性能和可重用…...

Ubuntu20.04编译安装Carla全过程

前言 Carla的安装是我现阶段解决的第一个问题&#xff0c;现记录一下我安装Carla的过程以及我在安装过程中遇到的一些问题。 一、安装前准备 1、硬件环境 carla是一款基于UE4开发的模拟仿真软件&#xff0c;本身对硬件的要求比较高。 我是windows与ubuntu双系统&#xff0…...

Dijkstra 算法 是什么?

Dijkstra 算法 Dijkstra 算法是一种经典的最短路径算法&#xff0c;用于在图&#xff08;有向或无向图&#xff09;中找到从起点到其他所有节点的最短路径。它以广度优先搜索的方式&#xff0c;逐步扩展到目标节点&#xff0c;确保计算出的路径是最短的。 1. Dijkstra 算法的基…...

英文输入法---华为OD机试2024年E卷

题解&#xff1a; 代码&#xff1a;...

理解 package.json 中版本号符号

今天&#xff0c;聊一聊在前端开发中&#xff0c; package.json 中怎么看版本号符号。 版本号符号的解释 版本号通常由三部分组成&#xff1a;主版本号、次版本号、补丁版本号&#xff0c;格式为 major.minor.patch。常见的符号有&#xff1a; ^&#xff1a;更新时允许自动…...

计算机网络-IPSec VPN基本概念

企业分支之间经常有互联的需求&#xff0c;企业互联的方式很多&#xff0c;可以使用专线线路或者Internet线路。部分企业从成本和需求出发会选择使用Internet线路进行互联&#xff0c;但是使用Internet线路存在安全风险&#xff0c;如何保障数据在传输时不会被窃取&#xff1f;…...

VsCode运行Ts文件

1. 生成package.json文件 npm init 2. 生成tsconfig.json文件 tsc --init 3. Vscode运行ts文件 在ts文件点击右键执行Run Code,执行ts文件...