邮箱功能简介
- 要在网络上实现邮件功能,必须要有专门的邮件服务器。直接百度即可,如qq邮箱的smtp服务器为
smtp.qq.com
-
协议
SMTP协议 发送邮件的协议
- 通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。
- 常用smtp端口一般是
465
/587
/25
具体看邮箱服务商的规定
- POP3协议 接收邮件的协议
- 通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。
IMAP:接收,它使用标准端口143和加密端口993。IMAP和POP3的主要区别是,IMAP协议在本地的所有操作都会自动同步到服务器上,并且,IMAP可以允许用户在邮件服务器的收件箱中创建文件夹。
准备
第三方代理收发邮件功能需要在邮箱服务中开启
smtp
和pop3
功能,并取得授权码导入依赖
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
发邮件
```java package com.boot.service;
import javax.mail.*; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.Properties;
public class EmailService { public static void main(String[] args) throws MessagingException { String smtp = “smtp.qq.com”; // 登录用户名(邮箱账号): String username = “1743430691@qq.com”; // 登录口令(第三方收发功能授权码): String password = “vqhjbasxvzsxccgg”; // 连接到SMTP服务器587端口: Properties props = new Properties(); //配置信息类,存储配置 props.put(“mail.smtp.host”, smtp); // SMTP主机名 props.put(“mail.smtp.port”, “587”); // 主机端口号 props.put(“mail.smtp.auth”, “true”); // 是否需要用户认证 props.put(“mail.smtp.starttls.enable”, “true”); // 启用TLS加密 // 获取Session实例: Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); // 设置debug模式便于调试: session.setDebug(true);
MimeMessage message = new MimeMessage(session);
// 设置发送方地址:
message.setFrom(new InternetAddress("1743430691@qq.com"));
// 设置接收方地址:
message.setRecipient(Message.RecipientType.TO, new InternetAddress("768854737@qq.com"));
// 设置邮件主题(标题):
message.setSubject("Hello", "UTF-8");
// 设置邮件正文:
message.setText("Hi Xiaoming...", "UTF-8");
// 发送:
Transport.send(message);
} }
<a name="tRihw"></a>
## 发送HTML邮件
- 把:`message.setText(body, "UTF-8");` 改为:`message.setText(body, "UTF-8", "html");`,body传入`html`代码字符串即可
- 不一定要传入完整的html源码,只传入部分就能识别,如传`<h1>Hello</h1><p>Hi, xxx</p>` 无需<html>这些即可
<a name="MZDfD"></a>
## 发送附件邮件
- 取消原本的`message.setText()`,改为构造Multipart对象,将内容,附件等信息传入Multipart中,然后`message.setContent(multipart)`
- 一个Multipart对象可以添加若干个BodyPart,其中第一个BodyPart是文本,即邮件正文,后面的BodyPart是附件
- 如果添加文本,用`setContent("...", "text/plain;charset=utf-8")`添加纯文本,或者用`setContent("...", "text/html;charset=utf-8")`添加HTML文本。
- 如果添加附件,需要设置文件名(不一定和真实文件名一致),并且添加一个`DataHandler()`,传入文件的MIME类型。二进制文件可以用`application/octet-stream`,Word文档则是`application/msword`。
```java
String body = "这是一封附件邮件...";
Multipart multipart = new MimeMultipart();
InputStream input=new FileInputStream("C:\\Users\\Lw\\Desktop\\sdfaf.txt");
// 添加内容:
BodyPart textpart = new MimeBodyPart();
textpart.setContent(body, "text/html;charset=utf-8");
multipart.addBodyPart(textpart);
// 添加附件:
BodyPart imagepart = new MimeBodyPart();
imagepart.setFileName("附件1.txt");
imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(input, "application/octet-stream")));
multipart.addBodyPart(imagepart);
// 设置邮件内容为multipart:
message.setContent(multipart);
// 发送:
Transport.send(message);
HTML邮件内嵌图片
一般情况下
<img>
引入的外部图片链接通常会被邮件客户端过滤,并提示用户显示图片并不安全。只有内嵌的图片才能正常在邮件中显示。- 在HTML邮件中引用图片时,需要设定一个ID,用类似引用
- 在添加图片作为BodyPart时,除了要正确设置MIME类型(根据图片类型使用
image/jpeg
或image/png
),还需要设置一个Header:imagepart.setHeader("Content-ID", "<img01>");
Multipart multipart = new MimeMultipart(); // 添加text: BodyPart textpart = new MimeBodyPart(); textpart.setContent("<h1>Hello</h1><p><img src=\"cid:img01\"></p>", "text/html;charset=utf-8"); multipart.addBodyPart(textpart); // 添加image: BodyPart imagepart = new MimeBodyPart(); imagepart.setFileName(fileName); imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(input, "image/jpeg"))); // 与HTML的<img src="cid:img01">关联: imagepart.setHeader("Content-ID", "<img01>"); multipart.addBodyPart(imagepart);
常见问题
常见问题
如果用户名或口令错误,会导致535登录失败:
DEBUG SMTP: AUTH LOGIN failed Exception **in** thread "main" javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful [HK0PR03CA0105.apcprd03.prod.outlook.com]
- 如果登录用户和发件人不一致,会导致554拒绝发送错误:
DEBUG SMTP: MessagingException **while** sending, **THROW**: com.sun.mail.smtp.SMTPSendFailedException: 554 5.2.0 STOREDRV.Submission.**Exception**:SendAsDeniedException.MapiExceptionSendAsDenied;
- 有些时候,如果邮件主题和正文过于简单,会导致554被识别为垃圾邮件的错误:
DEBUG SMTP: MessagingException **while** sending, THROW: com.sun.mail.smtp.SMTPSendFailedException: 554 DT:SPM
收邮件
很少需要用到这种功能,自己看:链接
springboot中发送Email
配置
spring: mail: host: smtp.qq.com port: 465 #587和465是qq邮箱smtp的2个端口,一个不行时换一个试试 username: 1743430691@qq.com password: nzsqldzfmuwnfbda protocol: smtp #协议 test-connection: true default-encoding: UTF-8 properties: mail.smtp.auth: true mail.smtp.starttls.enable: true mail.smtp.starttls.required: true mail.smtp.ssl.enable: true //qq邮箱需要开启ssl,别的不清楚 mail.display.sendmail: spring-boot-demo
依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!-- 模板引擎利于动态添加数据到html中--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
使用
不同类型的邮件有不同类,不过有一些通用方法
- setFrom(from);//发送者
- setTo(to);//接收者
- setSubject(title);//标题
- setText(txt);//内容 内容即便是html等,也是通过api传入html路径或者名称就会得到渲染后的源码字符串
- send(邮件对象);
- 见springboot-demo