JavaMail是JavaEE平台中用于收发邮件的标准规范,它支持SMTP、POP3和IMAP协议,它基本能够实现一个完整的邮件客户端。不过由于其历史比较古老,API也是设计的也是相对比较繁琐。这里我们简单学习如何基于JavaMail实现邮件发送。
JavaMail包含在JavaEE SDK中,如果我们的工程最终部署到JavaEE应用服务器,引入以下依赖即可。
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
不过如果我们不使用JavaEE平台,我们也可以单独引入如下两个Maven依赖。
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
其中,mail
模块是JavaMail相关的类和接口,activation
则是JAF相关的代码,它是JavaEE中用于处理MIME类型相关的模块,JavaMail依赖该框架。
这里我们采用一个普通Java工程演示JavaMail发送邮件的代码。下面例子中,我们发送了一封简单的文本邮件。
package com.gacfox.demo;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public class Main {
public static void main(String[] args) throws Exception {
// SMTP服务器设置
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.host", "SMTP服务器地址");
props.setProperty("mail.smtp.port", "SMTP服务器端口");
props.setProperty("mail.smtp.auth", "true");
// Session
Session session = Session.getInstance(props);
session.setDebug(true);
// Transport
Transport transport = session.getTransport();
transport.connect("登录用户名", "登陆密码");
// 构造邮件
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("发件人邮箱"));
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人邮箱"));
message.setSubject("测试邮件");
message.setContent("你好", "text/html;charset=UTF-8");
// 发送邮件
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
}
代码中实现发送邮件的基本步骤如下:
.properties
文件中transport.sendMessage()
发送邮件其实我们主要关心的就是发送的邮件如何构造,也就是步骤4,其他部分的代码都是相对比较固定的,实际开发中我们按照例子编写即可。
实际上邮件内容通常是HTML富文本,但是熟悉前端的开发人员不要高兴的太早,邮件中是没法引入CSS(但可以用一部分内联样式)、JavaScript的,发个图片也要指定图片文件的所在位置,毕竟邮件这种比较严肃的内容,一般不会做太花哨的格式。我们一般都会写一个HTML模板,然后用类似Velocity等引擎生成文件内容。
下面例子代码用Velocity引擎生成一个表格,然后构造为一个邮件的Message
对象。
// 测试数据
List<User> userList = new ArrayList<>();
userList.add(new User("tom", "123456"));
userList.add(new User("jerry", "root"));
userList.add(new User("lucy", "admin"));
// Velocity生成HTML
VelocityEngine engine = new VelocityEngine();
Properties veProps = new Properties();
veProps.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
veProps.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
engine.init(veProps);
Template template = engine.getTemplate("src/main/resources/template.vm");
VelocityContext context = new VelocityContext();
context.put("userList", userList);
StringWriter stringWriter = new StringWriter();
template.merge(context, stringWriter);
String mailMsg = stringWriter.toString();
// 构造邮件
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("发件人邮箱"));
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人邮箱"));
message.setSubject("测试邮件");
message.setContent(mailMsg, "text/html;charset=UTF-8");
HTML模板内容如下。
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>账户信息</title>
</head>
<body>
<h1>账户信息</h1>
<table>
<thead>
<tr>
<td>用户名</td>
<td>密码</td>
</tr>
</thead>
<tbody>
#foreach($u in $userList)
<tr style="background-color:
#if($velocityCount%2==0)
#c3f3c3
#else
#f3c3f3
#end
;">
<td>$u.username</td>
<td>$u.password</td>
</tr>
#end
</tbody>
</table>
<p style="color: red;"></p>
</body>
</html>
邮件收到的内容如下图。
有关Velocity的内容,参考Java应用程序开发/Velocity模板引擎
相关章节。
对于更复杂的邮件,通常还会在HTML中包含图片,以及携带邮件的附件,下面例子演示了如何构造这种非常复杂的邮件形式。
// 测试数据
List<User> userList = new ArrayList<>();
userList.add(new User("tom", "123456"));
userList.add(new User("jerry", "root"));
userList.add(new User("lucy", "admin"));
// Velocity生成HTML
VelocityEngine engine = new VelocityEngine();
Properties veProps = new Properties();
veProps.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
veProps.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
engine.init(veProps);
Template template = engine.getTemplate("src/main/resources/template.vm");
VelocityContext context = new VelocityContext();
context.put("userList", userList);
StringWriter stringWriter = new StringWriter();
template.merge(context, stringWriter);
String mailMsg = stringWriter.toString();
// 构造邮件
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("发件人邮箱"));
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人邮箱"));
message.setSubject("测试邮件");
MimeMultipart multipart = new MimeMultipart();
// 邮件正文部分
MimeBodyPart main = new MimeBodyPart();
main.setContent(mailMsg, "text/html;charset=UTF-8");
multipart.addBodyPart(main);
// 邮件图片加载
MimeBodyPart image = new MimeBodyPart();
DataHandler imgDataHandler = new DataHandler(new FileDataSource("src/main/resources/1.jpg"));
image.setDataHandler(imgDataHandler);
image.setContentID("img_1.jpg");
multipart.addBodyPart(image);
// 邮件附件加载
MimeBodyPart attach = new MimeBodyPart();
DataHandler attachDataHandler = new DataHandler(new FileDataSource("src/main/resources/新建文本文档.7z"));
attach.setDataHandler(attachDataHandler);
attach.setFileName(MimeUtility.encodeText(attachDataHandler.getName()));
multipart.addBodyPart(attach);
message.setContent(multipart);
在HTML模板中,我们需要使用如下形式引用图片。
<img src="cid:img_1.jpg" />