JavaMail邮件发送

Posted HackShendi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaMail邮件发送相关的知识,希望对你有一定的参考价值。

邮件协议

常见的电子邮件协议有SMTP,POP3,IMAP4,它们都隶属于TCP/IP协议簇
默认状态下,分别通过TCP端口25,110和143连接

SMTP(Simple Mail Transfer Protocol),简单邮件传输协议
用于从源地址到目的地址传输邮件规范,通过它来控制邮件的中转方式

POP,邮局协议
负责从邮件服务器中检索电子邮件,它要求邮件服务器完成以下任务之一
从邮件服务器中检索邮件并从服务器中删除这个邮件
从邮件服务器中检索邮件但不删除它
不检索邮件,询问是否有新邮件到达

IMAP,互联网信息访问协议
优于POP的新协议

先注册一个邮箱,在对应设置中开启指定协议,开启后会有一串授权码
例如网易邮箱

下载jar

官网: https://javaee.github.io/javamail/

使用了 Maven 则可直接通过以下方式引入

<dependencies>
   <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.6.2</version>
    </dependency>
</dependencies>

离线 Jar 则除 javax.mail.jar 之外还需要下载 JAF(JavaBeans Activation Framework)
JAF下载
下载完后使用的是 activation.jar

发送邮件

发送邮件使用 SMTP 协议

创建邮件会话(Session)

javax.mail.Session
有以下两个静态函数获取

获取默认的Session对象
Session.getDefaultInstance(Properties)
Session.getDefaultInstance(Properties, Authenticator)

获取一个新的Session对象
Session.getInstance(Properties)
Session.getInstance(Properties, Authenticator)

示例代码

Properties p = new Properties();
// 设置邮件服务器地址,在邮箱的设置面板里查看,我用的网易邮箱
p.setProperty("mail.host", "smtp.163.com");
// 发送邮箱的协议为 smtp
p.setProperty("mail.transport.protocol", "smtp");

// 如果要使用 ssl,则需要添加以下代码,应检查指定平台是否支持ssl
MailSSLSocketFactory msf = new MailSSLSocketFactory();
msf.setTrustAllHosts(true);
p.put("mail.smtp.ssl.enable", "true");
p.put("mail.smtp.ssl.socketFactory", msf);

// 创建session对象
Session s = Session.getDefaultInstance(p, new Authenticator() {
	@Override
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication("发送邮箱的邮箱地址,例如xxx@163.com", "授权码");
	}
});

Properties 属性

API描述

props- 属性对象。仅在创建新 Session 对象时使用。
期望客户端为 JavaMail 规范的附录 A 中列出的属性(特别是 mail.store.protocol、mail.transport.protocol、mail.host、mail.user 和 mail.from)提供值作为默认值不太可能在所有情况下都有效。

可在 Java mail附录A中查看

key描述默认值
mail.store.protocol指定默认的消息访问协议。Session.getStore()方法返回一个实现此协议的存储对象。客户端可以覆盖此属性,并使用Session.getStore(String协议)方法显式地指定该协议。配置文件中的第一个适当的协议
mail.transport.protocol指定默认的传输协议。Session.getTransport()方法返回一个实现此协议的传输对象。客户端可以覆盖此属性,并使用Session.getTransport(String协议)方法显式地指定协议。配置文件中的第一个适当的协议
mail.host指定默认的邮件服务器。如果没有协议特定的主机属性,则存储和传输对象的连接方法将使用此属性来定位目标主机。本地机器
mail.user指定在连接到邮件服务器时要提供的用户名。如果没有协议特定的用户名属性,则存储和传输对象的连接方法将使用此属性来获取该用户名。user.name
mail.protocol.host指定特定于协议的默认邮件服务器。这会覆盖mail.host属性mail.host
mail.protocol.user指定用于连接到邮件服务器的特定于协议的默认用户名。这会覆盖mail.user属性mail.user
mail.from指定当前用户的返回地址。由InternetAddress.getLocalAddress方法用于指定当前用户的电子邮件地址。username@host
mail.debug指定初始调试模式。将此属性设置为true将打开调试模式,而将其设置为false将关闭调试模式。请注意,Session.setDebug方法也控制了调试模式。false

开启调试模式

通过 s.setDebug(true) 来开启调试模式

创建邮件内容

MimeMessage 类表示一封邮件
代码示例如下

MimeMessage message = new MimeMessage(s);
// 邮件发送人
message.setFrom(new InternetAddress("xxx@163.com"));
// 邮件收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress("xxx@163.com"));
// 邮件标题
message.setSubject("标题");
// 邮件内容,可以是多内容(MimeMultipart)
message.setContent("内容", "text/html;charset=UTF-8");

多内容以及图片/附件

通过 MimeMultipart 类可以添加多个内容以及附件
代码示例如下

MimeMultipart mm = new MimeMultipart("mixed");
// 每一个 MimeBodyPart 代表一个内容
MimeBodyPart content = new MimeBodyPart();
content.setText("内容文本");

// 附件,同样也可以是图片
MimeBodyPart file = new MimeBodyPart();
DataSource ds = new FileDataSource(new File(文件地址));
DataHandler dh = new DataHandler(ds);
file.setDataHandler(dh);
file.setFileName("邮件中显示的附件名称");

// 添加到内容
mm.addBodyPart(text);
mm.addBodyPart(file);

// 邮件内容设置
message.setContent(mm);

发送邮件

通过 Transport 进行发送

Transport t = s.getTransport();
t.connect("smtp.163.com", "发送者邮箱地址@163.com", "授权码");
t.sendMessage(message, message.getAllRecipients());
t.close();

完整代码示例

Properties p = new Properties();
// 设置邮件服务器地址,在邮箱的设置面板里查看,我用的网易邮箱
p.setProperty("mail.host", "smtp.163.com");
// 发送邮箱的协议为 smtp
p.setProperty("mail.transport.protocol", "smtp");

// 如果要使用 ssl,则需要添加以下代码,应检查指定平台是否支持ssl
MailSSLSocketFactory msf = new MailSSLSocketFactory();
msf.setTrustAllHosts(true);
p.put("mail.smtp.ssl.enable", "true");
p.put("mail.smtp.ssl.socketFactory", msf);

// 创建session对象
Session s = Session.getDefaultInstance(p, new Authenticator() {
	@Override
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication("发送邮箱的邮箱地址,例如xxx@163.com", "授权码");
	}
});
		
// 开启调试模式
s.setDebug(true);

// 组装邮件
MimeMessage message = new MimeMessage(s);
// 邮件发送人
message.setFrom(new InternetAddress("xxx@163.com"));
// 邮件收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress("xxx@163.com"));
// 邮件标题
message.setSubject("标题");
// 邮件内容
MimeMultipart mm = new MimeMultipart("mixed");
// 每一个 MimeBodyPart 代表一个内容
MimeBodyPart content = new MimeBodyPart();
content.setText("内容文本");
// 附件,同样也可以是图片
MimeBodyPart file = new MimeBodyPart();
DataSource ds = new FileDataSource(new File(文件地址));
DataHandler dh = new DataHandler(ds);
file.setDataHandler(dh);
file.setFileName("邮件中显示的附件名称");
// 添加到内容
mm.addBodyPart(text);
mm.addBodyPart(file);
// 邮件内容设置
message.setContent(mm);

// 发送邮件
Transport t = s.getTransport();
t.connect("smtp.163.com", "发送者邮箱地址@163.com", "授权码");
t.sendMessage(message, message.getAllRecipients());
t.close();

补充: 指定端口

Properities配置添加端口

p.setProperty("mail.port", "端口号");

Transport连接时指定端口

t.connect("smtp.163.com", 端口, "发送者邮箱地址@163.com", "授权码");

以上是关于JavaMail邮件发送的主要内容,如果未能解决你的问题,请参考以下文章

Android Java使用JavaMail API发送和接收邮件的代码示例

javamail电子邮件不发送

JavaMail邮件发送

JavaMail邮件发送

Spring集成JavaMail并利用线程池发送邮件

邮件实现详解------JavaMail 发送(带图片和附件)和接收邮件