这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
使用JavaMail收发送电子邮件,包括带有附件和内嵌图片的邮件!
Email就是电子邮件。发邮件是从客户端把邮件发送到邮件服务器,收邮件是把邮件服务器的邮件下载到客户端,Java同样提供了收发邮件的API。
163、126、QQ、sohu、sina等网站都提供了邮件服务,这些网站都有自己的邮件服务器,我们自己的Email用户页面实际上就相当于客户端。
1 邮件协议
1.1 邮件协议
与HTTP协议相同,收发邮件也是需要有传输协议的:
- SMTP:(Simple Mail Transfer Protocol,简单邮件传输协议)发邮件协议;
- POP3:(Post Office Protocol Version 3,邮局协议第3版)收邮件协议;
- IMAP:(Internet Message Access Protocol,因特网消息访问协议)收发邮件协议。
这些协议都属于应用层协议。
1.2 理解电子邮件收发过程
其实你可以把邮件服务器理解为邮局!如果你需要给朋友寄一封信,那么你需要把信放到邮筒中,这样你的信会“自动”到达邮局,邮局会把信邮到另一个省市的邮局中。然后这封信会被送到收信人的邮箱中。最终收信人需要自己经常查看邮箱是否有新的信件。
其实每个邮件服务器都由SMTP服务器和POP3服务器构成,其中SMTP服务器负责发邮件的请求,而POP3负责收邮件的请求。
当然,有时我们也会使用163的账号,向126的账号发送邮件。这时邮件是发送到126的邮件服务器,而对于163的邮件服务器是不会存储这封邮件的。
1.3 邮件服务器名称
smtp服务器的端口号为25,服务器名称为smtp.xxx.xxx。
pop3服务器的端口号为110,服务器名称为pop3.xxx.xxx。
例如:
- 163: smtp.163.com和pop3.163.com;
- 126: smtp.126.com和pop3.126.com;
- qq: smtp.qq.com和pop3.qq.com;
- sohu: smtp.sohu.com和pop3.sohu.com;
- sina: smtp.sina.com和pop3.sina.com。
2 JavaMail
2.1 JavaMail概述
JavaMail是由SUN公司提供的专门用于Java收发邮件的API,使用Java程序发送邮件时,我们无需关心SMTP协议的底层原理,只需要使用JavaMail这个标准API就可以直接发送邮件。
JavaMail中主要类有javax.mail.Session、javax.mail.internet.MimeMessage、javax.mail.Transport
。
- Session: 表示会话,即客户端与邮件服务器之间的会话!想获得会话需要给出账户和密码,当然还要给出服务器名称。在邮件服务中的Session对象,就相当于连接数据库时的Connection对象。
- MimeMessage: 表示邮件类,它是Message的子类。它包含邮件的主题(标题)、内容,收件人地址、发件人地址,还可以设置抄送和暗送,甚至还可以设置附件。
- Transport: 用来发送邮件。它是发送器!
2.2 maven依赖
使用JavaMail的API我们需要引入对应的jar包或者maven依赖:
1 | xml复制代码<!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail --> |
jar包下载地址为:mvnrepository.com/artifact/co…
2.3 JavaMail发送邮件
我们使用smtp协议发送邮件!
2.3.1 简单邮件
发送一个简单的邮件需要三步:
- 根据服务器参数和认证器信息来获取Session实例;
- 根据Session创建MimeMessage对象,MimeMessage中包含了各种可以设置的邮件属性
- 通过Transport发送邮件
简单的案例如下:
1 | java复制代码/** |
2.3.2 发送HTML文本
有时候我们的邮件正文可能是一个HTML页面,发送方式和上面的案例完全一致,只需要注意编码格式为“text/html;charset=utf-8”,后面的字符集要与html文本的字符集一致。
当然,也可以发送图片资源等等。
1 | java复制代码/** |
结果:
2.3.3 发送附件
如果想发送带有附件邮件,那么需要设置邮件的内容为MimeMultiPart,而不仅仅是一段文本。
多部件对象MimeMultiPart,可以理解为是部件的集合。一个Multipart对象可以添加若干个BodyPart,其中第一个BodyPart是文本,即邮件正文,后面的BodyPart是附件,最后将MimeMultiPart设置到msg的content中。
案例如下:
1 | java复制代码/** |
结果:
2.3.4 发送内嵌图片HTML
发送的HTML文本的内嵌图片可以采用网络链接,也可以使用本地图片。本地内嵌图片实际上也是一个附件,即邮件本身也是Multipart,但需要做一点额外的处理。
在HTML邮件中引用图片时,需要设定一个ID,用类似引用,然后,在添加图片作为BodyPart时,除了要正确设置MIME类型(根据图片类型使用image/jpeg或image/png),还需要设置ContentID为img1与HTML的中的img 标签的img1关联。
1 | java复制代码/** |
2.4 JavaMail收取邮件
我们使用pop3协议收取邮件!
1 | java复制代码public class ReceiveEmail { |
2.5 相关异常
- Exception in thread “main” com.sun.mail.smtp.SMTPSendFailedException: 554 DT:SPM
- 一般是被邮件服务器识别为垃圾邮件,可以换个复杂点的主题和内容,或者换台主机发送。这很麻烦,比如在运行上面的案例时就有可能抛出这样的异常!
- Exception in thread “main” javax.mail.AuthenticationFailedException: 535 Error: authentication failed
- PasswordAuthentication中的用户登陆信息错误,可能是密码或者授权码错误。
- Exception in thread “main” com.sun.mail.smtp.SMTPSendFailedException: 553 Mail from must equal authorized user
- 如果用户信息和发件人信息不一致
3 总结
本次我们学习了使用JavaMail的API简单的收发邮件的过程,电子邮件的收发需要使用道SMTP和POP3协议。在实际开发中,这样的底层API我们用的比较少,因为代码编写很麻烦,因此本文了解就行了。
在实际项目开发中,常常使用Spring框架为我们提供的更高级的发送邮件的API。
如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!
本文转载自: 掘金